Использование splice в редукторе (redux) - PullRequest
1 голос
/ 09 мая 2020

Я создаю свое первое приложение на React и Redux. Я пытаюсь удалить элемент из массива в моем редукторе с помощью splice.

Вот мое состояние:

  favourite: { recipes: [], wines: [], products: [] }

Вот мое действие:

  if (action.type === "REMOVE_RECIPE_FROM_FAV") {
    let favourite = state.favourite;
    favourite.recipes.splice(action.data, 1);
    return {
      ...state,
      favourite: favourite,
    };
  }

Когда я в избранное console.log, я вижу, что удаляю элемент, но мой компонент не обновляется.

Не могли бы вы мне помочь?

Ответы [ 3 ]

1 голос
/ 09 мая 2020

Вы должны позаботиться о неизменности состояния redux. Вам нужно сделать копию массива recipes, изменить его и объединить с состоянием, не затрагивая другие.

if (action.type === "REMOVE_RECIPE_FROM_FAV") {
    let favourite = state.favourite;
    const cloneRecipes = [...favourite.recipes];
    cloneRecipes.splice(action.data, 1);

    return {
        ...state,
        favourite: {
            ...state.favourite,
            recipes: cloneRecipes
        }
    }
}

Обратите внимание, что [...favourite.recipes] делает неглубокую копию recipes массив. Для вложенного массива это вам не поможет.

Я предлагаю вам использовать вместо этого Immutability Helpers . Используя эту библиотеку, можно выполнить ту же задачу, например:

if (action.type === "REMOVE_RECIPE_FROM_FAV") {
    return update(state, {
        favourite: {
            recipes: {$splice: [[action.data, 1]]}
        }
    });
}
0 голосов
/ 09 мая 2020

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

Однако здесь вы изменяете состояние, поскольку переменная favourite, которую вы создаете , не содержать копию избранного объекта в вашем состоянии, но просто ссылку на него . Следовательно, когда вы используете splice, вы фактически изменяете исходный массив recipes, а не создаете новый, поэтому Redux не может обнаружить, что он изменился, поскольку это фактически тот же объект!

To Чтобы избежать этой проблемы, вы можете сделать что-то вроде этого:

if (action.type === "REMOVE_RECIPE_FROM_FAV") {
  return {
    ...state,
    favourite: {...favourite, 
                recipes: { state.favourite.recipes.slice(action.data, action.data + 1) }
    }
  };
}

Я предполагаю, что action.data содержит индекс удаляемого элемента.

0 голосов
/ 09 мая 2020

Как сказал Робин Зигмонд, вы должны вернуть новое состояние из редуктора, а не изменять его, поэтому вместо этого используйте array.filter, чтобы удалить action.data из избранного массива.

    let favourite = state.favourite;
    // this return new items array removing action.data from it.
    let newFavouriteArray = favourite.filter(item => item !== action.data)
    return {
      ...state,
      favourite: newFavouriteArray,
    };
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...