2016-07-31 69 views
0

我正在爲我的應用程序使用redux與react和typescript。我正在使用在我的應用程序的不同位置使用的很多項目。我的狀態是這樣的:使用redux設計一個大型狀態的高效減速器

{ 
    items: {42: {}, 53: {}, ... }, //A large dictionary of items 
    itemPage1: { 
     items: [42, 34, 67, ...], 
     ... 
    }, 
    itemPage2: { ... 
    }, 
    ... 
} 

我想寫一個有效的項目減速,但項目是大,我不能創建深層副本各一次。顯然我不需要根據gaearon(從there中提取):Redux並不要求您在每個動作上深入克隆狀態。它只是要求你爲已經改變的零件返回新的對象。您可以重複使用以前的狀態來查看樹中沒有更改的任何部分。

這太好了!但是,我對這一切都很陌生,我不確定如何正確實施減速器。我至今我的項目機內部是這樣的:

case UPDATE_ITEM_LABEL: 
    return (<any>Object).assign({}, state, { 
      item_id: (<any>Object).assign({}, state[action.item_id], { 
       label: action.value 
      }) 
    }) 

所以它複製老態的所有元素到一個新的對象,然後用新的更新後的值改變的對象合併的結果。我希望在第一個assign期間的項目通過引用傳遞,因此不會被深度複製?如果這樣的話可以,因爲我可以承受深度複製一個項目和一些簡單的參考每個行動。此外,我發現有可能使用immutable.js來回答這個問題,如果我提出的方法正在工作,爲什麼人們會使用immutable.js?

+1

不可變將嘗試高效地重用現有數據。目的是避免必須自己做出這樣的決定。 –

回答

0

我做了一個簡單的測試,以確保我的方法做的工作:

var item1 = {prop1: 'item1', prop2: 'haha'}; 
var item2 = {prop1: 'item2', prop2: 'hehe'}; 
var items = {1:item1, 2:item2}; 

console.log(items); 

這顯示預期:

[object Object] { 
    1: [object Object] { 
    prop1: "item1", 
    prop2: "haha" 
    }, 
    2: [object Object] { 
    prop1: "item2", 
    prop2: "hehe" 
    } 
} 

現在我們用assign得到下一個狀態,修改item2的其中一個鍵:

var items = Object.assign({},items, { 2: Object.assign({}, items[2], 
    { 
     prop2: 'huhu' 
    }) 
}); 

console.log(items); 

按預期方式顯示此屏幕:​​

[object Object] { 
    1: [object Object] { 
    prop1: "item1", 
    prop2: "haha" 
    }, 
    2: [object Object] { 
    prop1: "item2", 
    prop2: "huhu" 
    } 
} 

現在有趣的一點,如果我們使用初始參考物品1和ITEM2改變prop1屬性:

item1.prop1 = 'ITEM1' 
item2.prop1 = 'ITEM2' 

console.log(items); 

我們發現,只有ITEM2深受複製,這是我想要的行爲:

[object Object] { 
    1: [object Object] { 
    prop1: "ITEM1", 
    prop2: "haha" 
}, 
    2: [object Object] { 
    prop1: "item2", 
    prop2: "huhu" 
    } 
} 
+0

你應該把它分解成單獨的reducer並使用'combineReducers' – naomik