'Removing an specific item from an array in React

i have this code https://stackblitz.com/edit/react-wc2ons?file=src%2FSection.js

I have sections, and i can add items to those sections. How can i delete some item? I tried

const removeItem = (i) => {
    setSections((section) => {
      const itemTarget = section.items[i];
      const filtered = section.items.filter((item) => item !== itemTarget);
      return {
        ...section,
        items: filtered,
      };
    });
  };

But for some reason it doesn't work



Solution 1:[1]

You are using setSections, but you return a single section instead of an array of sections. You probably need something like this:

// using the `section` variable from the upper scope
const removeItem = (i) => {
    setSections((sections) => {
      const itemTarget = section.items[i];
      const filtered = section.items.filter((item) => item !== itemTarget);
      const newSections = [...sections];
      newSections[section.id] = {
        ...section,
        items: filtered,
      };
      return newSections;
    });
  };

A few tips (you don't have to follow them): TypeScript can prevent such mistakes and give useful error messages. Immer.js can make writing such code simpler.

Solution 2:[2]

The removeItem callback prop you pass into the Section component is the way to go and you should get rid of passing setSections down to it as well.

removeItem={(i) => removeItem(index, i)}

Child components shouldn't do parent's work so you had it right at first, I'm going to help you implement that since I can already see the removeItem handler being there in the App component.

removeItem has already all the info you need, I'm going to rename the arguments so it's more clear.

const removeItem = (sectionIndex, index) => {
  const newSections = sections.slice();
  const newItems = newSections[sectionIndex].items.slice();
  
  newItems.splice(index, 1);
  newSections[sectionIndex].items = newItems;
  
  setSections(newSections);
};

Then get rid of removeItem implementation in the Section component and destructure it from the props.

Solution 3:[3]

Your problem is that section is an array. So you are currently accessing the undefined property items on it. You would have to change your function to something like this

  const removeItem = (i) => {
    setSections((section) /* aqui vc tinha chamado de prev*/ => {
      const itemTarget = section[i].items[j];
      const filtered = section[i].items.filter((item) => item !== itemTarget);
      return [...section, {
        ...section[i],
        items: filtered,
      }]
    });
  };

where i is the section in question and j is the item you want to delete.

Solution 4:[4]

here is a crude solution to your problem (i noticed other bugs in the code but this solves your issue with removing items at least), but i would separate the sections and items into separate components that in turn has its own states. There you can add/remove items withing its parent section much more easily.

Now we have to work around this by looking for which section the code wants to remove the current item in.

https://stackblitz.com/edit/react-xxbvp1?file=src%2FSection.js

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 georch
Solution 2 Ioannis Potouridis
Solution 3 Gh05d
Solution 4 Fredrik Krig