Reputation: 13
Hello guys I had a problem. I don't know it is a bug or not but I think it is a bug. I would open an issue on github repo of react but first I wanted to look at here and ask to you. I will give you all my code on the bottom of this post
What is the problem?
I am connection a socket when my component first mounted and catched the user to connect live chat. And I use useState to set messages when I or agent send a messsage on message event. I use useState on the line of 114. First of all this useState(setMessages on ) works correctly. But If I set the setMessages by the other ways this won't work.
For Example 1: If I set this setMessages like below, setMessages works correctly and changes state but messages state not rendering on DOM correctly. I didn't udnerstand what's wrong.
const dummy = [...messages]
dummy.push(data.messageData)
setMessages(dummy)
For Example 2: If I set this setMessages like below, setMessages doesn't work and I got an error and I never see my rendered page because it say ...prev is a null. I didn't understand what's wrong again.
setMessages((prev) => [...prev, data.messageData])
For Example 3: This is the most interesting part of my code. It's really impossible one. If I remove line 111 and 112 (those are below here) the version of runs correctly of my codes doesn't work and setMessages doesnt work by the way with concat either. And I don't use those codes anywhere you can see that by using Ctrl+F. I just described those to set setMessages with the dummy variable but that didn't work and now I can't delete them because if I delete them my working codes won't work either.
const dummy = messages
dummy.push(data.messageData)
Now guys what's wrong on there. I fight all day with this buy I didnt find any reason. Is it a bug or not? Have a good days I will be here for your replies.
This is all of my codes in the page that I have a problem
https://gist.github.com/mucahidyazar/5ccff6d67d95d23dfb470dfe026f714b
Upvotes: 1
Views: 1299
Reputation: 8774
You are using the useState incorrectly and its not a problem with react ;)
You need to create a new object reference if you use setState.
For example a string, number or boolean are always new instances.
But this does not work for objects. Push keeps the old object reference and setting a value to the same reference as before to the useState hook will be skipped.
const dummy = messages
dummy.push(data.messageData)
setMessages(dummy)
You are passing he same object to the setState (here setMessages) than before (push only adds the item to the same obejct), but you need a new instance instead, or else react will not rerender.
setMessages((prev) => [...prev, data.messageData])
but this only works if the default item is an array, so make sure you are setting ... = useState([])
so that prev is defined.
For line 111, yes the current object receives the new items, so the console.log shows the correct data,but since its the same instance (push does not create a new instance of the array), the rerender gets skipped and you will not see any changes on the resulting website.
o when I take a look at your code, change this:
const dummy = messages
dummy.push(data.messageData)
console.log(dummy)
setMessages(messages.concat(data.messageData).slice(0, messages.length)
to
setMessages([...messages, data.messageData])
Upvotes: 1