2017-04-20 66 views
1

我正在使用Redux,最近遇到了一個問題,那就是我要將消息添加到數組中,並且Redux狀態不是正在發出在React上重新渲染。我正在使用react-redux庫。下面是我遇到的問題的一個例子:Spread運算符vs JSON.parse(JSON.stringify(...))用於不可變對象

// State structure 
structure: { messages: {}, groups: {} } 

// --- 
newState = { ...prevState }; 
newState.messages[action.message.group] = action.message; 
return newState; 

這是更新狀態,但是它沒有觸發更新的反應成分,但是與newState = JSON.parse(JSON.stringify(prevState))更換newState = { ...prevState }解決了這個問題。

任何人都可以解釋爲什麼這發生在細節?我的印象是,傳播操作符創建了對象的克隆,直到現在我從來沒有遇到任何問題。

+0

我想你應該使用這個「Object.assign」。沒有直接替換原點值,因爲我們一般不會改變狀態。 (http://redux.js.org/docs/basics/Reducers.html) – Wei

+0

傳播運算符只是一個淺拷貝,而不是像序列化/反序列化方法那樣的深層拷貝。這可能會影響事情。 – ShadowRanger

回答

5

react-redux連接的組件執行淺層嚴格的相等性檢查以決定是否要更新。請參閱http://redux.js.org/docs/faq/ImmutableData.html

傳播運算符與Object.assign類似,並且不會深入克隆對象。 JSON工作原因是因爲你創建了一個全新的對象,可以通過嚴格的相等性檢查,但是所有的組件都會不必要地更新,因爲現在沒有任何事情會通過嚴格的相等性檢查。 Object.assign({},... prevState,... newState)將創建一個新的頂級對象,但它不會爲嵌套在prevState或newState中的任何對象創建一個新對象。但是,您必須仔細更新嵌套對象以避免不必要的重新呈現。對於深度嵌套的對象和數組,這可能會變得棘手。

我建議檢查管理狀態的無縫不可變或不可變的包。此外,重新選擇庫可以幫助您提取特定於組件需求的記憶對象。

+0

這是發生問題的唯一位置,它讓我們感到有點矯枉過正,在我們使用過幾個月的應用程序中加入了一個庫。在遷移到MBaaS時,我們正在改變數據結構並遇到了這個問題,您知道這是唯一的用例,您認爲什麼是最佳行動方案?你覺得導入一個圖書館是必要的,或者應該對此進行序列化/反序列化工作嗎?我有一個自定義'componentShouldUpdate'來阻止基於緩存的不必要的渲染,所以這應該不成問題。 – Hobbyist

+0

我想說,如果應用程序正在工作,並且您目前沒有任何性能問題,那麼完整的重新渲染似乎並不是當前的問題。以後切換到無縫不可變非常簡單。 – chris