-
Notifications
You must be signed in to change notification settings - Fork 47.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
React Hooks useState updating an array #15041
Comments
Function components capture the values that they rendered with. That includes effects capturing state that belongs to that render. So what happens in your initial example is that:
Any time new message is received, the socket handling it is the one created in first render. That socket uses So the root of the problem is that you don’t actually want setMessages(msgs => msgs.concat(JSON.parse(msg.data))); That works correctly: https://codesandbox.io/s/x7x24oxlzz. As a side note, Hope this helps! |
Thanks so much @gaearon! |
Thanks @gaearon 🙇 |
Thank you so much for the detailed explanation and remedy - just ran into this exact issue, it was even a chat UI! |
Thanks so much @gaearon! |
Awesome @gaearon! |
Does array.push() works ? |
thanks , resolved it, help me to much @gaearon |
Do you want to request a feature or report a bug?
Hooks Clarification
What is the current behavior?
I'm trying to understand the lifecycle of
useState
.I have a mock application using a mock websocket. Every second, it sends a new message from the backend. The new message is meant to be appended to an array using
useState
.Here are a few different examples that highlight my confusion:
Example 1
In this example, if I set the websocket's
onmessage
function once inuseEffect
, then whenever I callsetMessages
to update themessages
array, themessages
array I receive as an input is empty.The effect of this is that I only ever get the latest message in my array.
Example 2
If, however, I set the
onmessage
function on every render as in this example, then I get my full array with data appended as I would expect.In the
receiveMessage
function, mymessages
array is the whole array instead of an empty one in this example.Example 3
BUT, if I assign a new reference to
messages
, as in this example, and re-assign the value insidereceiveMsg
, then I don't have to re-assign theonmessage
function over and over.Example 4
But, if I assign a new reference and don't re-assign to it, as in this example, I continue ending up with an empty array. This suggests it's the assignment back to
msgRef
that is keeping the entire array within the closure.What is the expected behavior?
My original expectation was that example #1 would work. I can tell there's something I'm not totally understanding about the way the assignment of variables to closure works with this hook, but I'm struggling to define what exactly's going on. Can someone shed some light on why this works this way?
Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?
React 16.8
The text was updated successfully, but these errors were encountered: