2016-07-31 63 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