簡體   English   中英

替換深子對象,同時在React中保持狀態不變

[英]Replace deep child object, while keeping state immutable in 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來制作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;
    }
}

是否有人清楚這是為什么被錯誤標記: A state mutation was detected inside a dispatch

您試圖變異一個不可變的東西。 因此,錯誤。

不可變項的全部要點是,不可變項創建后永遠不應該在其內部的任何位置進行更改。 這就是為什么所有更改它的函數都會創建一個不可變的新實例。 如果您嘗試更改不可變內部的內容,那仍然是一個突變,因此很糟糕。

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

您應該做的就是對其進行突變(如果您使用的是immutables庫,則可以使用setIn ),這將創建一個新的Map。 您可以僅在state上調用它。

像這樣:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM