2017-05-25 21 views
0

我是新來的反應和redux。我有一個對象是子對象,其中包含數組替換深的子對象,同時保持狀態在React中不可變

const initialState = { 
    sum: 0, 
    denomGroups: [ 
     { 
      coins: [ 
       { name: 'Penny', namePlural: 'Pennies', label: '1¢', value: .01, sum: 0 }, 
       { name: 'Nickel', namePlural: 'Nickels', label: '5¢', value: .05, sum: 0 }, 
       { name: 'Dime', namePlural: 'Dimes', label: '10¢', value: .10, sum: 0 }, 
       { name: 'Quarter', namePlural: 'Quarters', label: '25¢', value: .25, sum: 0 } 
      ] 
     }, 
     { 
      bills: [ 
       { name: 'Dollar', namePlural: 'Dollars', label: '$1', value: 1, sum: 0 }, 
       { name: 'Five', namePlural: 'Fives', label: '$5', value: 5, sum: 0 }, 
       { name: 'Ten', namePlural: 'Tens', label: '$10', value: 10, sum: 0 }, 
       { name: 'Twenty', namePlural: 'Twentys', label: '$20', value: 20, sum: 0 }, 
       { name: 'Fifty', namePlural: 'Fiftys', label: '$50', value: 50, sum: 0 }, 
       { name: 'Hundred', namePlural: 'Hundreds', label: '$100', value: 100, sum: 0 } 
      ] 
     } 
    ] 
}; 

數組我有被傳遞一個值,面額

export function increaseSum(value, denom) { 
    return { type: types.ADD_TO_SUM, value: value, denom: denom } 
} 

裏面我減速的我寫了一個名稱的行動輔助類,以查明該教派是對象中:

function findDenomination(denoms, action) { 
    let denomMap = {}, 
     currentDenom = {}; 
    for (let i = 0; denoms.length >= i + 1; i++) { 
     let denomGroup = denoms[Object.keys(denoms)[i]]; 
     for (var key in denomGroup) { 
      if (!currentDenom.length) { 
       currentDenom = denomGroup[key].filter(x => x.name === action.denom); 
       if (currentDenom.length > 0) { 
        denomMap.group = i; 
        denomMap.key = key; 
        denomMap.index = denomGroup[key].findIndex(x => x.name === action.denom); 
       } 
      } 
     } 
     if (currentDenom.length > 0) { 
      break; 
     } 
    } 
    return denomMap; 
} 

和減速器本身我使用Object.assign使denomGroup的深層副本以我認爲保持不變的方式。

function countableItems(state = initialState, action) { 
    switch (action.type) { 
     case types.ADD_TO_SUM: 
      let denomMap = findDenomination(state.denomGroups, action); 
      state.denomGroups = Object.assign({}, state.denomGroups, state.denomGroups[denomMap.group][denomMap.key][denomMap.index].sum = parseFloat(action.value)); 
      return state; 
     default: 
      return state; 
    } 
} 

是明確告訴任何人這是爲什麼越來越有錯誤標記:A state mutation was detected inside a dispatch

+1

你修改狀態:'state.denomGroups = ...'' – Li357

+1

返回Object.assign({},狀態,state.denomGroups [denomMap.group] [ denomMap.key] [denomMap.index] .sum = parseFloat(action.value));'仍然拋出突變錯誤 –

+0

'state.denomGroups [denomMap.group] [denomMap.key] [denomMap.ind ex] .sum = parseFloat(action.value)'仍然是一個狀態變異 – Li357

回答

1

試圖變異不可改變的。因此錯誤。

不可改變的重點是,創建後,不可變的永遠不應該改變它內部的任何位置。這就是爲什麼所有改變它的函數都會創建一個不可變的新實例。如果你試圖改變一個不可變的東西,那仍然是一個變種,因此是不好的。

這確保您只需檢查對象本身是否相等,而不必進行深入檢查,並確保數據完整性。

你應該做的只是改變它(如果你正在使用immutables庫,你可以使用setIn),這將創建一個新的地圖。你可以打電話給state

事情是這樣的:

case types.ADD_TO_SUM: 
    const denomMap = findDenomination(state.denomGroups, action); 
    return state.setIn(['denomGroup', denomGroup.key, denomGroup.index, sum], parseFloat(action.value)); 
+0

你是否總是使用'immutables'庫? –

+1

雖然完整的答案比我在這裏有更多的空間,總之,我嘗試了某些事情,比如Redux狀態。最大的好處是,如果你有一個不可變的數據,當你將它傳遞給一個'React.PureComponent'時,它可以可靠地確定(不需要深度檢查),如果對象改變了,是否需要重新渲染。 – samanime

相關問題