最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Using splice in reducer (redux) - Stack Overflow

programmeradmin0浏览0评论

I'm building my first application with React and Redux. I'm trying to delete an item from an array in my reducer using splice.

Here my state:

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

Here my action:

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

When i console.log favourite i can see that I'm deleting the item, but my ponent doesn't update.

Could you please help me?

I'm building my first application with React and Redux. I'm trying to delete an item from an array in my reducer using splice.

Here my state:

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

Here my action:

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

When i console.log favourite i can see that I'm deleting the item, but my ponent doesn't update.

Could you please help me?

Share Improve this question asked May 9, 2020 at 13:03 Davide Davide 772 silver badges4 bronze badges 4
  • do you mind to show code where you are getting and using this favourite variable? – Uma Commented May 9, 2020 at 13:06
  • 8 reducers must return new data, not merely mutate it. splice mutates. As far as Redux is concerned, favourite has not changed, as the reference is still the same. – Robin Zigmond Commented May 9, 2020 at 13:08
  • I agree with @RobinZigmond so you must spread into a new array, see my answer below. – Fasani Commented May 9, 2020 at 13:13
  • Does this answer your question? Is this the correct way to delete an item using redux? – wentjun Commented May 9, 2020 at 13:20
Add a ment  | 

3 Answers 3

Reset to default 3

You have to take care of the immutibility of the redux state. You need to make a copy of the recipes array and change it and merge with the state without affecting the others.

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

Note that, the [...favourite.recipes] makes a shallow copy of the recipes array. For a nested array, it does not help you.

I suggest you to use Immutability Helpers library instead. By using this library the same task could be done like:

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

As Robin Zigmond said that you must return a new state from reducer not mutate it so instead use array.filter to remove the action.data from the favourite array.

    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,
    };

Your reducers should be pure functions, meaning that they should not mutate the state passed in.

However, here you are modifying the state, since the favourite variable that you create does not contain a copy of the favourite object in your state, but just a reference to it. Therefore, when you use splice, you are actually modifying the original recipes array, not creating a new one, so Redux is not able to detect that it has changed, since it's actually the same object!

To avoid this problem, you could do something like this:

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

I'm assuming that action.data contains the index of the element to remove.

发布评论

评论列表(0)

  1. 暂无评论