2017-03-16 91 views
0

我觉得我的减速器应该工作,但它一直坚持我在改变状态。更新减速器中的对象属性,无突变

Uncaught Error: A state mutation was detected inside a dispatch, in the path: output.outputList.0.composition . Take a look at the reducer(s) handling the action {"type":"SET_OUTPUT_COMPOSITION",

我几个小时前发布了类似的答案,但没有答案,但我认为我的redux状态太复杂了。这是我的简化版本,我仍然得到mutate错误..我做错了什么?我是否应该在我的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} 
} 
+0

你可以包括你的动作加入 –

+0

@DavidBradshaw行动,你将ty – user1189352

+0

我发现我需要这里的答案http://stackoverflow.com/questions/35362460/replace-array-item-with-another-one-without- mutating-state – user1189352

回答

1

spread operator不深拷贝在你原来的列表中的对象:

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

这是一个浅拷贝,因此

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

你实际上是变异先前的状态对象,你在说您的评论有几种方法可以解决此问题,使用切片/拼接创建阵列的新实例等。

您还可以看一看t使用ImmutableJS,通常我会说在redux存储中存储类会使事情有点难以理解,我倾向于使用简单的结构,可以使用redux工具轻松检查。

0

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

+0

啊,我希望你会是正确的..我把类变成一个psuedo类,它是一个函数,只是返回一个对象具有相同的属性,但仍然得到相同的错误。另外,当我在减速器中放置一个断点时,我会看到它一路通过,它会得到同样的错误,尽管它一旦尝试返回新的状态就像以前一样。 – user1189352

+0

如果您发送字符串,会发生什么情况? –