2017-04-26 39 views
0

我有一個看起來像這樣的深度嵌套Redux的狀態:React/Redux - 我如何製作深度嵌套狀態的副本?

{ 
    name: "Item One", 
    children: [ 
    { 
     name: "Item Two" 
     children: [ 
      .... 
     ] 
    }, 
    { 
     name: "Item Three", 
     children: [ 
      .... 
     ] 
    } 
    ] 
} 

我需要它的副本,這樣我就可以方便地修改它,然後用它來取代原本的狀態。

不幸的是,僅僅使用{... state}不起作用,因爲所有嵌套的子元素都沒有被複制,他們仍然引用相同的對象。有沒有一個方便的解決方法?

回答

0

爲最簡單的快捷方式是:

const clone = JSON.parse(JSON.stringify(state)); 

總而言之,涉及克隆對象的問題,有幾個關於這個問題的答案在那裏,這取決於東西,如:

  1. 在那裏發揮作用在源對象的引用,
  2. 是有DOM涉及的元件,
  3. Date對象,
  4. 更多...

但是在這種情況下,你是在處理一個»純JSON對象«,因爲它是終極版狀態,所以上述方法會奏效。

另一種方式是一個遞歸函數,將所有嵌套的數據,但如上所述,在這種情況下,你沒有這樣做,因爲你不必擔心DOM元素或其他的東西一樣。

+0

我認爲Redux建議該對象一般可序列化。然而,'JSON.parse'的一個重要警告(因爲函數可能不應該是狀態的一部分)是'Date'(de)序列化。 – CodingIntrigue

+0

我更新了我的答案,並將日期對象添加到列表中。然而,這絕對是「快速和骯髒」的方法,但如果你知道沒有任何「複雜」的成員,它將工作沒有太多的代碼。 – philipp

1

有幾個選項:

  1. 使用其中有一些優秀的docs on the React siteupdate immutability helper
  2. 使用包像這對這種事情進行了優化。

我推薦第一個,因爲語法特別強大,特別是在處理像Redux商店這樣的大型結構時。

正如從文檔的例子:

import update from 'immutability-helper'; 

const newData = update(myData, { 
    x: {y: {z: {$set: 7}}}, 
    a: {b: {$push: [9]}} 
}); 

讓您無需擔心現有對象危險的突變修改深度嵌套的特性。