【问题标题】:Updating Object Property in Reducer without Mutation在没有变异的情况下更新 Reducer 中的对象属性
【发布时间】:2017-08-07 06:41:20
【问题描述】:

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

未捕获的错误:在调度中检测到状态突变,路径为:output.outputList.0.composition。看看处理动作 {"type":"SET_OUTPUT_COMPOSITION",

的 reducer

几个小时前我发布了类似的内容,但没有答案,但我认为我的 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;

用于更新属性的减速器

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}
}

【问题讨论】:

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


【解决方案1】:

错误来自dispatch。所以它甚至没有达到reducer。我希望它不喜欢你使用class 来定义output。相反,只需执行const output ={ ... }

【讨论】:

  • 啊,我希望你是正确的。我把这个类变成了一个伪类,它是一个函数,它只返回一个具有相同属性的对象,但仍然得到相同的错误。此外,当我在减速器中放置一个断点时,我看到它一直运行,但当它像以前一样尝试返回新状态时,它会得到相同的错误。
  • 如果改为发送字符串会发生什么?
【解决方案2】:

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

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

这是一个浅拷贝,因此

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

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

你也可以使用ImmutableJS看看.

【讨论】:

    猜你喜欢
    • 2018-08-29
    • 2016-12-24
    • 2011-03-01
    • 1970-01-01
    • 2011-09-02
    • 1970-01-01
    • 2016-12-17
    • 2019-09-01
    • 1970-01-01
    相关资源
    最近更新 更多