2017-08-09 79 views
0

的對象屬性我已經瞭解到,爲了修改位於狀態的屬性或子對象,不能直接在setState中設置它。相反,我需要在我的函數中創建一個對象的副本,並首先在那裏修改它。我接着做返航使用的setState整個變化的對象,如下圖所示:修改位於狀態

constructor(props) { 
    super(props) 
     this.state = { 
      item: this.props.item, 
      success: false 
     } 
} 

和:

handleChange(event){ 
    let item = this.state.item; 

    const target = event.target; 
    let value = target.type === 'checkbox' ? target.checked : target.value; 
    const id = target.id; 

    item[id] = value; 

    this.setState({ 
     item: item, 
     success: true 
    }) 
} 

有一件事我不知道,但是,是對象是通過引用複製。這意味着行item[id] = value自動更新狀態。從setState函數中刪除item: item行會有什麼傷害,如下所示?

this.setState({ 
     success: true 
    }) 

問題1:它的工作方式很好,但是有沒有這樣做的副作用?

問題2:另一方面,保持原始setState的方式是否有任何危害?由於item已經在狀態中更新,因此再次更新它似乎不會有任何傷害。

問題3:會更有意義,使對象的完整副本,而不是第一個,因此避免這一整個問題,如下列:

let item = JSON.parse(JSON.stringify(this.state.item)); 

回答

0

我建議你this article。除此之外,您可以使用const item = { ...this.state.item }而不是對該對象進行串接和解析。如果您注意到,我已使用const而不是letconst定義會很好,直到您嘗試用新值更改整個變量。我的意思是,如果你只是更新一個對象的const變量的屬性就沒有問題。

根據這種可變的反應狀態,我認爲這並不理想。因爲React檢查變量引用。在你的情況下,參考沒有改變。但是由於success,虛擬DOM獲得了不同。

2

我瞭解到,爲了修改位於狀態的屬性或子對象,不能直接在setState中設置它。相反,我需要在我的函數中創建一個對象的副本,並首先在那裏修改它。

你不是被迫這樣做的。這是一種常見的做法,因爲通過這種方式,您可以使用淺層比較來了解何時發生了變化並優化了渲染性能。我強烈建議你閱讀官方指南的這一段落明白我在說什麼:

那說:

但是,我沒有意識到的一件事是,對象被引用複製。這意味着訂單項[ID] =值會自動更新狀態。
問題1:這樣做很好,但是這樣做有沒有副作用?

通過引用複製對象,是的,因此item[id] = value確實會更改狀態值。但是不會自動觸發組件的重新渲染。所以,狀態的變化,但你的觀點並不反映這種變化。它在你的情況下工作,因爲在該指令之後,你撥打setState,這是一個改變狀態(再次)觸發重新呈現的功能。如果您之後沒有(或不需要)撥打setState,您需要需要才能調用this.forceUpdate()來觸發重新渲染,並且您的視圖將反映「手動」狀態更改。

問題2:另一方面,保持原始setState的方式是否有任何傷害?由於項目已經在狀態中更新,似乎不應該再次更新它。

這個問題在這一點上沒有意義。現在應該清楚你會發生什麼。

問題3:會更有意義,使對象的完整副本,而不是第一個,因此避免這整個問題,比如下面的

關於我聯繫手冊中的東西,有道理給你之前。但是使用JSON編碼製作對象的副本是沒有用的。有更好的方法,在那個鏈接中描述。

希望我清楚,樂於助人!