I'm trying to create a resuable component that will be able to take a function passed down into it, allowing it to update the state of the parent component. I've got a demo on CodeSandbox that shows the issue.
TrackListing is passed the removeTrack function from the parent, and when the delete button is clicked inside the TrackListing, the function is called with the rows index to be removed from the tracks state. Unfortunately this doesn't seem to update the tracks state.
CodePudding user response:
Your not changing the state, tracks
it's the same tracks
.
In JS if you do -> var a = [1,23]; var b = a; console.log(a === b);
it would return true
. Assigning an array to another var, does not make a new array.. Doing var a = [1,23]; var b = [...a]; console.log(a === b);
will do a shallow copy of a, and this as expected will return false
. IOW: In react causing a state change.
Also splice(index,index)
, I'm pretty sure you meant splice(index, 1)
.
const removeTrack = (index: number) => {
const t = tracks;
t.splice(index, index);
console.log(t);
setTracks(t); //t is still the same instance of t.
};
So you will need to make a copy of t
.
const removeTrack = (index: number) => {
const t = tracks;
t.splice(index, 1);
setTracks([...t]); //lets make a copy of `t` state has changed.
};
As pointed out in the comments, using the callback version of setState
is a good idea, it will prevent issues of scope, here scope isn't an issue, but it's easy to get caught out by it.
Also another issue I've found with your current implementation you might want to look into, using array index
as a key is not a good idea, it's not unique and you could get some funky rendering quirks, you really need unique id
s for your tracks to use as the key
eg. This bit ->
tracks.map((track, index) => (
<tr key={index}> //not a good idea.
tracks.map((track, index) => (
<tr key={track.id}> //much better
Also when it comes to deleting, use the track id, using the callback/filter version in comments from Ali, you could also then just change removeTrack(track:Track) {}
, and pass the track. IOW: remove index array positions from all code.
I've done a fork of your CodeSandBox with these changes to make it easier. CodeSandBox