2017-03-16 93 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

如果您發送字符串,會發生什麼情況? –