Reputation: 1037
I've seen this problem on SO, but I cannot seem to work out why it exists.
I am following the tutorial from here
I am using useState but when I try to update the state, the array is empty. I am using state to create initially an empty array. on message received, I am trying to add the message to the array, using the spread operator, which I have used countless times to add an object to an array (but never inside useEffect).
If I uncomment the commented lines, "chat" gets updated as it should do, but I cannot understand why the spread operator is not working and I need to use a useRef to make this work. I don't want to have loads of useRef for every corresponding useState (at least not knowing why it is necessary)
Can anyone see what I am doing wrong, or explain why I need the useRef?
const [chat, setChat ] = useState([]);
//const latestChat = useRef(null);
//latestChat.current = chat;
// ...
useEffect(() => {
if (connection) {
connection.start()
.then(result => {
console.log('Connected!');
connection.on('ReceiveMessage', message => {
const newMsg = {
user: message.user,
message:message.message
}
setChat([...chat, newMsg]); // issue with this line. chat is always empty
//const updatedChat = [...latestChat.current];
//updatedChat.push(message);
//setChat(updatedChat);
});
})
.catch(e => console.log('Connection failed: ', e));
}
}, [connection]);
Upvotes: 3
Views: 4400
Reputation: 6582
you have two option here
chat
state to useEffect dependency array
so it knows it depends on chat
.useEffect(() => {
if (connection) {
//...
setChat([...chat, newMsg]); // issue with this line. chat is always empty
//...
}
}, [connection, chat]);
setState callback
to update chat
so you won't get stale data
useEffect(() => {
if (connection) {
//...
setChat((ch) => [...ch, newMsg]); // issue with this line. chat is always empty
//...
}
}, [connection]);
which the second way is more appropriate.
Upvotes: 8