Редукс редуктор - это мутирует состояние? - PullRequest
0 голосов
/ 12 марта 2019

Я столкнулся со следующим редукторным редуктором, и хотя он работает нормально, я считаю, что это неправильно:

export default (state = initState, action) => {
    switch (action.type) {
        case RESET_SCREEN:
            return Object.assign({}, state, initState);
        case MODIFY_ITEM:
            let itemId = state.item.id;
            state.items[itemId].item = action.item;
            return Object.assign({}, state, {items: state.items});
    }
}

Правильно ли, что RESET_SCREEN хорош, потому что он не изменяет состояние, однако часть MODIFY_ITEM плоха, потому что она мутирует? В каких случаях это будет больно? (потому что приложение в настоящее время ведет себя как ожидалось)

Какая альтернатива для MODIFY_ITEM?

Ответы [ 4 ]

1 голос
/ 12 марта 2019

Верно ли, что RESET_SCREEN хорош, потому что он не изменяет состояние

Да, это правильно.

однако часть MODIFY_ITEMплохо, потому что он мутирует

Нет, MODIFY_ITEM не изменяет состояние:

Эта строка: state.items[itemId].item = action.item; мутирует объект (не состояние), но reduxне заботится о локальной мутации объекта - он даже не узнает.

Пока вы возвращаете новую ссылку - новую копию объекта, redux считает ее действительным новым состоянием.

Итак, согласно приставке,
Это мутация состояния:

case MODIFY_ITEM:
        let itemId = state.item.id;
        state.items[itemId].item = action.item;
        return state; // <-- because you are returning the same reference. BAD

Это не мутация состояния:

case MODIFY_ITEM:
    let itemId = state.item.id;
    state.items[itemId].item = action.item;
    return Object.assign({}, state, {items: state.items}); // <- A new Object. GOOD

Возможно, вы захотите прочитать омелкая проверка и мутация состояния здесь .

0 голосов
/ 12 марта 2019

Вы можете использовать npm immer .

Это крошечный пакет, который позволяет вам работать с неизменяемым состоянием более удобным способом. Он основан на механизме копирования при записи .

0 голосов
/ 12 марта 2019

Чтобы сохранить неизменность состояния, вы можете написать обработчик действия MODIFY_ITEM следующим образом:

case MODIFY_ITEM:
    let itemId = state.item.id;
    return {...state, items: state.items.map((item, index) => {
        return index === itemId ? action.item : item
    })}
0 голосов
/ 12 марта 2019

Вы изменяете предыдущее состояние в этой строке

state.items[itemId].item = action.item;
...