Подтвердить что ты не робот

Это правильный способ удалить элемент с помощью сокращения?

Я знаю, что я не должен мутировать входные данные и должен клонировать объект, чтобы мутировать его. Я следовал соглашению, используемому в проекте стартового стартера, который использовал:

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() 
})

но это мутирует объект входного состояния - это запрещено, хотя я возвращаю новый объект?

4b9b3361

Ответ 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() 
})