Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/406.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 替换深层子对象,同时在React中保持状态不变_Javascript_Reactjs_Redux_Immutability - Fatal编程技术网

Javascript 替换深层子对象,同时在React中保持状态不变

Javascript 替换深层子对象,同时在React中保持状态不变,javascript,reactjs,redux,immutability,Javascript,Reactjs,Redux,Immutability,我是一个新的反应和重复。我有一个对象是一个包含数组的子对象数组 const initialState = { sum: 0, denomGroups: [ { coins: [ { name: 'Penny', namePlural: 'Pennies', label: '1¢', value: .01, sum: 0 }, { name: 'Nickel', namePlur

我是一个新的反应和重复。我有一个对象是一个包含数组的子对象数组

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 }
}
在我的reducer中,我编写了一个helper类来标识该名称在对象中的位置:

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;
}
在reducer本身中,我使用
Object.assign
来制作denomGroups的深度副本,我认为这样做可以保持denomGroups的不变

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

任何人都清楚为什么这会被标记为错误:
在调度中检测到状态变异

您试图变异不可变的。因此出现了错误

不可变的全部要点是,不可变的内容在创建之后,不应在其内部的任何地方发生更改。这就是为什么所有改变它的函数都会创建一个不可变的新实例。如果你试图改变一个不可改变的东西,那仍然是一种变异,因此是不好的

这确保了您只需检查对象本身是否相等,而无需进行深入检查,并确保数据完整性

您应该做的只是对它进行变异(如果您使用的是
不可变
库,您可以使用
setIn
),这将创建一个新映射。你可以在
状态下调用它

大概是这样的:

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

您正在修改状态:
state.denomGroups=…
return Object.assign({},state,state.denomGroups[denomMap.group][denomMap.key][denomMap.index].sum=parseFloat(action.value))仍然抛出一个变异错误
state.denomGroups[denomMap.group][denomMap.key][denomMap.ind‌​ex].sum=parseFloat(action.value)
仍然是一种状态变化。您是否倾向于始终使用
不可变的
库?虽然完整的答案比我这里的答案更大,但简而言之,我尝试对某些事情进行修改,比如Redux状态。最大的好处是,如果您有一个不可变的数据,当您将其传递给
React.PureComponent
时,它可以可靠地确定(无需深入检查)对象是否更改以及是否需要重新渲染。