【问题标题】:How to update a value of a nested object in a reducer?如何更新减速器中嵌套对象的值?
【发布时间】:2017-02-27 00:09:51
【问题描述】:

我已经建立了这样的状态

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 中更新其活动状态?我也愿意就如何更好地改善我的状态提供反馈

【问题讨论】:

    标签: redux immutable.js


    【解决方案1】:

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

    根据文档,另请注意,如果您的数据存储在规范化结构中,更新特定项目会更容易,因为您可以直接通过 ID 查找它。 “Structuring Reducers”部分也涵盖了规范化。

    【讨论】:

      【解决方案2】:

      这是很常见的事情,实际上,相当令人生畏。据我所知,在纯 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
      猜你喜欢
      • 2019-04-06
      • 2017-07-19
      • 1970-01-01
      • 1970-01-01
      • 2021-02-10
      • 1970-01-01
      • 1970-01-01
      • 2015-06-25
      • 2017-09-22
      相关资源
      最近更新 更多