在没有变异的情况下更新Reducer中的对象属性

时间:2017-03-16 07:51:55

标签: javascript reactjs ecmascript-6 redux react-redux

我觉得我的减速机应该工作,但它一直坚持我正在改变状态。

  

未捕获错误:在调度内部检测到状态突变:路径:output.outputList.0.composition。看一下处理动作的减速器{“type”:“SET_OUTPUT_COMPOSITION”,

我在几个小时之前发布了类似的内容而没有答案,但我认为我的redux状态太复杂了。这是我的简化版本,我仍然会遇到变异错误..我做错了什么?我不应该在我的redux状态下使用一个类吗?我应该使用某种不可变的库吗?请帮帮我。

我的初始Redux状态

output: {
    outputList: [], //composed of Output class objects
    position: 0
  }

输出类

class Output {

  constructor(output) {
      this.id = output.id;
      this.composition = output.getComposition();
      this.outputObj = output;
      this.name = output.name;
      this.url = output.getUrl();    
  }
}

export default Output;

用于更新属性的Reducer

case types.SET_OUTPUT_COMPOSITION: {
      let outputListCopy = Object.assign([], [...state.outputList]);
      outputListCopy[state.position].composition = action.composition;
      return Object.assign({}, state, {outputList: outputListCopy});

动作

export function setOutputComposition(comp) {
 return { type: types.SET_OUTPUT_COMPOSITION, composition: comp}
}

2 个答案:

答案 0 :(得分:1)

spread operator不会深层复制原始列表中的对象:

let outputListCopy = Object.assign([], [...state.outputList]);

这是一个浅层副本,因此

outputListCopy[state.position].composition = action.composition;

您实际上正在改变以前的状态对象,正如您在评论中所述,有几种方法可以解决此问题,使用切片/拼接来创建数组的新实例等。

你也可以看看使用ImmutableJS,一般来说我会说在redux商店中存储类会让事情变得有点难以理解,我倾向于使用简单的结构,可以用redux轻松检查-tools。

答案 1 :(得分:0)

错误来自dispatch。所以它甚至没有达到reducer。我希望您不喜欢使用class来定义output。而只是做const output ={ ... }