I'm trying to remove an element from the array inside an arrays of objects in React using UseState hook, but struggling to get the result, because the interface does not re-render and the object does not removing from it.
As I know, to get any updates of objects reflected in react UI, I should replace a whole object instead of updating it. I was trying to create a copy of an array and assign it through setDives method inside the function, but nothing.
Here is my code:
Declaring const using useState. I need to delete only specific guides by name ("Lee" or "John" in this example):
const [dives, setDives] = useState([
{ boat: 'Marcelo', divesite: '', guides: ['Lee', 'Jhon'] },
]);
Delete function:
function deleteGuide(i, guide) {
var tempArray = dives;
tempArray[dives.indexOf(i)].guides = dives[dives.indexOf(i)].guides.filter(
(e) => e !== guide,
);
setDives(tempArray);
}
Buttons in interface:
{dives.map((i) => (
<div>
{dives[dives.indexOf(i)].guides.map((guide) => (
<ButtonGroup>
<Button>{guide}</Button>
<Button onClick={() => deleteGuide(i, guide)}></Button>
</ButtonGroup>
))}
</div>
))}
You correctly said, that you have to create a new copy of the Array, but you are actually not doing it. That's why it is not working.
Change this line: setDives(tempArray);
to this: setDives([...tempArray]);
Explanation: When just setting tempArray, you are updating only the reference, which does not change, because tempArray = dives
. Since there are no changes, there is no re-render and you do not see any results. By using the spread-operator ...
, a completely new Array is constructed and therefor the state changes (which triggers a re-render).
Further reading: https://react.dev/learn/updating-arrays-in-state
To make this even more understandable, you can add a console.log before your setDives(tempArray)-statement and take a look at the output:
console.log(tempArray === dives); //will always return true, so no change
setDives([...tempArray]);