如何在reducer中更新嵌套对象的值?

时间:2016-10-17 21:33:56

标签: redux immutable.js

我已经建立了我的状态

const list = {
  categories: {
   Professional: {
    active: false,
    names: [
      {
        id: 1,
        name: "Golf",
        active: false
      },
      {
        id: 2,
        name: "Ultimate Frisbee",
        active: false
      }
  ] 
}}

在我的操作中,我添加了ID选项,因此当用户点击选项时,我想更改活动状态

我使用的是Immutable JS虽然没有和它结婚。我想知道如何定位对象的id并在reducer中更新其活动状态?我也愿意就如何更好地改善我的状态提出反馈

2 个答案:

答案 0 :(得分:37)

这是非常普遍的事情,而且实际上非常令人生畏。据我所知,普通JS中没有真正优秀且采用良好的解决方案。最初,使用了Object.assign方法:

return Object.assign({}, state, {
  categories: Object.assign({}, state.categories, {
    Professional: Object.assign({}, state.Professional, {
      active: true
    })
  })
});

我承认这太简单和麻烦了,但我不得不说我们用这种方法构建了很少的大型应用程序,除了字符数量之外它还不错。如今,最流行的方法是使用Object spread

return {
  ...state,
  categories: {
    ...state.categories,
    Professional: {
      ...state.categories.Professional,
      active: true
    }
  }
}

第二种方法更清洁,所以如果你使用普通JS,那么它似乎是一个不错的选择。 在Immutable.js中,我不得不承认它更容易,你只需要做下一个

return state.updateIn(['categories', 'Professional'], x => x.set('active', true));

但它有自己的缺点和警告,所以最好在承诺之前认真考虑它。

关于改善状态的最后一个问题 - 通常最好不要进行如此深度的嵌套(将您的关注点分开,通常字段不依赖于彼此 - 例如active状态可以分离到另一个对象),但由于不了解您的域名,很难说。此外,normalize您的数据被认为是正常的事情。

答案 1 :(得分:4)

Structuring Reducers上的Redux文档部分介绍了这一点。特别是,请参阅Immutable Update Patterns部分。给出的示例适用于普通的JS对象和数组,但同样的方法适用于列表上的map(),为想要更新的所有内容返回现有项目,并返回 想要更新的新版本。

根据文档,还要注意,如果您的数据存储在规范化结构中,则更新特定项目会更容易,因为您可以直接通过ID查找。 “结构化减速器”部分也涵盖了标准化。