I have this inside my component:
const [ pendingMessages, setPendingMessages ] = React.useState([]);
React.useEffect(function() {
ref.current.addEventListener('send-message', onSendMessage);
return function() {
ref.current.removeEventListener('send-message', onSendMessage);
};
}, []);
function onSendMessage(event) {
const newMessage = event.message;
console.log('Here not up to date :(', pendingMessages);
setPendingMessages([ ...pendingMessages, newMessage ]);
}
The problem is that pendingMessages
is not up to date inside the listener because it's not inside the render. It's already attached. Any ideas how can I resolve this?
Thanks!
I have this inside my component:
const [ pendingMessages, setPendingMessages ] = React.useState([]);
React.useEffect(function() {
ref.current.addEventListener('send-message', onSendMessage);
return function() {
ref.current.removeEventListener('send-message', onSendMessage);
};
}, []);
function onSendMessage(event) {
const newMessage = event.message;
console.log('Here not up to date :(', pendingMessages);
setPendingMessages([ ...pendingMessages, newMessage ]);
}
The problem is that pendingMessages
is not up to date inside the listener because it's not inside the render. It's already attached. Any ideas how can I resolve this?
Thanks!
Share Improve this question asked Feb 5, 2019 at 6:27 Mati TucciMati Tucci 2,9766 gold badges30 silver badges42 bronze badges1 Answer
Reset to default 19The problem is because of a close that is formed when the effect is run. Since you set the useEffect
to run only on initial mount, it gets the value of pendingMessages
from the closure that is formed when it is declared and hence even if the the pendingMessages
updates, pendingMessages
inside onSendMessage
will refer to the same value that was present initially.
Since you do not want to access the value in onSendMessage
and just update the state based on previous value, you could simply use the callback pattern of setter
const [ pendingMessages, setPendingMessages ] = React.useState([]);
React.useEffect(function() {
ref.current.addEventListener('send-message', onSendMessage);
return function() {
ref.current.removeEventListener('send-message', onSendMessage);
};
}, []);
function onSendMessage(event) {
const newMessage = event.message;
setPendingMessages(prevState =>([ ...prevState, newMessage ]));
}