Thanks for illustrating this @chico1992
🙏 That's the point I was trying to articulate.
I just did a search and found that at some point, React 16.7(ish?) made a change which uses an object identity check in the implementation of useState; the result is that the setter will do nothing if it is called with the same object that is currently memoized.
This is relevant because it implies that the object given to the setter is stored by reference, not copied and stored by value, and thus can be mutated without interacting with the setter as long as you have a reference to it. 😓
Ok so you're saying that since it's memorized as reference I could copy the array - not the reference - generated by the .json() into a new variable and then use setList to insert the reference of the new object into the state, instead of directly setting it?
Yes you should always pass a new state to the set state and not mutate it i guess your useing a method somewhere that mutates the array stored in your state
Since hooks are based on functional principels you should be very careful with mutating your state
Const doesn’t prevent mutating an array or an object
Okay, new tests led to this:
Now when I console.log([...res]) the array shows both of the fields, but then when I setList([...res]); console.log(list) it shows only the first value... I have no idea of the reason.
I've created a pastebin with the whole code: pastebin.com/AAkyJusJ
Also this is the image of what my console is now:
Don't mind those errors as they're not about the code itself, but they're generated by react-md-components.
can you try following code and tell us the what you get in the console
if your console.log spits out the right thing you are somewhere mutating your list
Edit: based on your screenshots it looks like you have a
list.shift()
somewhereThanks for illustrating this @chico1992 🙏 That's the point I was trying to articulate.
I just did a search and found that at some point, React 16.7(ish?) made a change which uses an object identity check in the implementation of
useState
; the result is that the setter will do nothing if it is called with the same object that is currently memoized.This is relevant because it implies that the object given to the setter is stored by reference, not copied and stored by value, and thus can be mutated without interacting with the setter as long as you have a reference to it. 😓
Ok so you're saying that since it's memorized as reference I could copy the array - not the reference - generated by the .json() into a new variable and then use setList to insert the reference of the new object into the state, instead of directly setting it?
Yes you should always pass a new state to the set state and not mutate it i guess your useing a method somewhere that mutates the array stored in your state
Since hooks are based on functional principels you should be very careful with mutating your state
Const doesn’t prevent mutating an array or an object
Okay, new tests led to this:
Now when I
console.log([...res])
the array shows both of the fields, but then when IsetList([...res]); console.log(list)
it shows only the first value... I have no idea of the reason.I've created a pastebin with the whole code: pastebin.com/AAkyJusJ
Also this is the image of what my console is now:
Don't mind those errors as they're not about the code itself, but they're generated by react-md-components.
the error is the following line since splice muatest the array
splice doc
const elem = list.splice(i, i + 1)[0];
btw you should run your fetch logic in a useEffect since it's a side effect
Ah! There's your problem on line 56:
The
splice
method is a mutator: it changes what's in yourlist
state!Here's the doc for details, but basically you need to use a different approach for extracting the element you want there.
I think
slice
should work:developer.mozilla.org/en-US/docs/W...
or even
const elem = list[i]
if I'm not mistaken
Yeah definitely! 👏
Oh God I though I was using .slice... All this trouble for a p.. I can't believe it.
Thanks to both of you, you were life saver, I would have probably rewritten the entire code to find this.