使用redux为大型州设计有效的减速器

时间:2016-07-31 14:41:05

标签: typescript redux react-redux immutable.js

我正在为我的应用程序使用带有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 :(得分: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"
  }
}

现在有趣的是,如果我们使用对item1和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"
  }
}