【问题标题】:Am in mutating the state in this reducer?正在改变这个减速器的状态吗?
【发布时间】:2016-09-19 19:53:37
【问题描述】:

我一直在阅读有关避免改变状态的不同方法。其中一种方法是使用扩展运算符 (...),而避免使用的方法之一是 push。但是在我的减速器中,我需要将一个项目添加到嵌套结构内的数组中,我无法正确实现 concat 所以我尝试了以下代码:

export default function (state=[],action){
 if (action.type === 'SELECTED_DROP') {   
     let updated = [ ...state];
     updated[action.payload.queryIndex].items.push(action.payload.item) ;   
     return updated; 
  }
return state;
}

所以,我同时使用:扩展运算符和推送。我在改变状态吗?

谢谢

【问题讨论】:

    标签: redux immutability react-redux


    【解决方案1】:

    是的,你正在改变状态。从我收集的状态来看,您的状态是一个数组,其中包含一个属性 items 的对象,这也是一个数组。您正在修改 items 数组,因此您正在改变状态。

    这是你应该做的:

    export default function (state=[], action) {
      switch (action.type) {
        case 'SELECTED_DROP':
          return state.map((item,ix) =>
            ix===action.payload.queryIndex ?
              {...item, items:[...item.items, action.payload.item]} :
              item
          );
        case default:
          return state;
      }
    }
    

    如果未更改,map 函数基本上返回旧项目,如果索引正确,则返回带有新项目数组的新项目。

    【讨论】:

      【解决方案2】:

      是的,你绝对是。您正在制作顶层数组的浅拷贝,但直接改变了内部数组。

      不可变更新数据有两个基本规则:

      • 每一层嵌套都需要复制一份
      • 您可以使用变异,但在您对实际副本进行变异时

      在这种情况下,您需要复制顶部数组、该索引处的项目、items 数组本身。嵌套更新可能会有点难看,但事实就是如此。

      我在react-redux-links 有很多关于如何正确编写不可变更新代码的文章的链接,在react-redux-links & Immutable Update Utilities 有很多实用程序库的链接以抽象出这些更新。

      【讨论】:

      • 感谢您的帮助。我会检查那些库。使用嵌套状态很痛苦。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-14
      • 2019-06-11
      • 2017-07-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多