在項目中經常會遇到各種需要修改、編輯的操作,一般的思路就是點擊編輯的時候,通過record獲取到這一整行數據存入當前的state中,然后將這個state值傳到編輯的頁面中,在編輯界面中,通過this.props.傳過來的名稱去獲取所有數據,當發生改變時,需要將當前修改的值傳到從父組件,然后父組件去修改之前的state。這樣的思路是沒有任何問題的,但是在寫法上面,使自己犯了一個很嚴重的錯誤,錯誤案例如下:假如我編輯表格的一行數據,我編輯都是可以改變的,但是我還沒點擊確定,表格的那一行數據也發生了改變,這就導致了我如果編輯了這一行數據,但是我最后點擊了取消按鈕,編輯模態框消失,但是表格的這一行數據還是發生了改變,盡管這個改變沒有存放到數據庫中,對于這個問題之前一直沒有想明白是為什么,不得已只能采取粗暴的解決辦法了,在編輯點擊取消按鈕之后,我重新發了一次請求,重新獲取表格數據,這樣才暫時隱藏了這個問題。昨晚也是一個類似的問題,然后冰哥教了我一大招,我這才恍然大悟。
之前關于編輯的一般寫法是:
editEnumsDesc(desc,index){
? const a = this.state.editData;//把這個對象賦值給a
? ? let b = [];
? ?if(a.ext.enums){
? ? ? ? ?b = a.ext.enums;
? ?}
? ?for(let i=0;i< b.length;i++){
? ? ? ? if(i === index){
? ? ? ? ? ? b[i].desc = desc;//雖然說這里還沒有setState,但是也相當于在操作editData ? ? ? ? ??
? ? ? ?}
? ?}
? a.ext.enums = b;
? ?this.setState({
? ? ? ?editData:a
? ?});
}
然后冰哥幫我改了一下代碼:
寫法一:
consta=JSON.parse(JSON.stringify(this.state.editData));
a.ext.enums[index].desc=desc;
this.setState({
? ? ? ? editData:a
});
寫法二:
this.setState((prevState)=>{prevState.editData.ext.enums[index].value=value});
原來最大的問題:就在于最初的賦值,也就是對象的復制問題。
百度了一下,關于對象的復制也是大有文章的,主要分為兩種類型:深復制和淺復制。
數據類型主要分為:簡單數據類型(Boolean、Null、Undefined、Number、String、Symbol)和復雜數據類型(Object)。
“=”主要用于簡單數據類型的賦值問題,如果用在Object中,例如存在Object b={'value':'111'},a = b;那么當a中改變value的值時,b中的value值也改變了。Object a 是等于 Object b的。
深復制和淺復制主要是針對Object而言的,淺復制只復制一層對象的屬性,而深復制則遞歸復制了所有層級。也就是說淺復制只賦值了對象的第一層屬性,當對象的第一層屬性發生改變的時候,兩個對象互不影響,但是當第二層對象發生改變的時候,兩個對象都會發生改變。而深復制不會這樣,兩個對象徹徹底底是不一樣的,會不影響。
淺復制就是簡單的引用:
var src = {
name:"src"
}
//復制一份src對象的應用
var target = src;
target.name ="target";
console.log(src.name);//輸出target
深復制的方法:JSON.parse(JSON.stringify());
var source = {
? name:"source",
? child:{
? ? ? ?name:"child"
? }
}
var target = JSON.parse(JSON.stringify(source));
//改變target的name屬性
target.name ="target";
console.log(source.name);//source
console.log(target.name);//target
//改變target的child
target.child.name ="target child";
console.log(source.child.name);//child
console.log(target.child.name);//target child
以上方法都是個人總結,如有錯誤,歡迎指正!