Это правильный способ удалить элемент с помощью сокращения?
Я знаю, что я не должен мутировать входные данные и должен клонировать объект, чтобы мутировать его. Я следовал соглашению, используемому в проекте стартового стартера, который использовал:
ADD_ITEM: (state, action) => ({
...state,
items: [...state.items, action.payload.value],
lastUpdated: action.payload.date
})
для добавления элемента - я получаю использование спреда для добавления элемента в массив.
для удаления я использовал:
DELETE_ITEM: (state, action) => ({
...state,
items: [...state.items.splice(0, action.payload), ...state.items.splice(1)],
lastUpdated: Date.now()
})
но это мутирует объект входного состояния - это запрещено, хотя я возвращаю новый объект?
Ответы
Ответ 1
Нет. Никогда не мутируйте свое состояние.
Даже если вы возвращаете новый объект, вы все еще загрязняете старый объект, который вы никогда не захотите делать. Это делает его проблематичным при сравнении старого и нового состояний. Например, в shouldComponentUpdate
, который реагирует-редуккс использует под капотом. Это также делает невозможным путешествие во времени (т.е. Отменить и повторить).
Вместо этого используйте неизменяемые методы. Всегда используйте Array#slice
и никогда Array#splice
.
Я предполагаю из вашего кода, что action.payload
- это индекс удаляемого элемента. Лучший способ был бы следующим:
items: [
...state.items.slice(0, action.payload),
...state.items.slice(action.payload + 1)
],
Ответ 2
Вы можете использовать метод фильтра массива для удаления определенного элемента из массива без изменения исходного состояния.
return state.filter(element => element !== action.payload);
В контексте вашего кода он будет выглядеть примерно так:
DELETE_ITEM: (state, action) => ({
...state,
items: state.items.filter(item => item !== action.payload),
lastUpdated: Date.now()
})
Ответ 3
Метод ES6 Array.prototype.filter
возвращает новый массив с элементами, которые соответствуют критериям. Поэтому в контексте исходного вопроса это будет:
DELETE_ITEM: (state, action) => ({
...state,
items: state.items.filter(item => action.payload !== item),
lastUpdated: Date.now()
})