As you can see in my problem below, I receive a message with the action stop. There I update 3 state variables. My problem is with the setTotalScore. totalScore is 0 in the beginning, and when I receive the message, I update it to be the same as the user.score. But, if I receive the message again, it is 0 again, even though it shouldn't be. I have read everywhere that it is a problem with how useState updates. I don't really know how to work around that. Here is the code:
socket.on(`${WsTopic.GAME}/${WsAction.STOP}`, (payload) => {
const user = payload.find((entry: any) => entry.username == name)
if (user) {
console.log("USER: ", user," USER.SCORE: ", user.score);
console.log("SCORE: ", totalScore);
const addedScore = user.score - totalScore;
setTotalScore(user.score);
setAddedScore(addedScore);
setShowAnswer(true);
}
})
const [totalScore, setTotalScore] = useState<number>(0);
The totalScore should always be updated and equal to the user.score. You can look at it like the totalScore is the prevScore of the user.score.
This is a Javascript closure issue, the socket closes over the
totalScorestate value from the render cycle where the socket event handler is instantiated and handed off to the socket.You can use a
useEffectwith proper dependencies to re-enclose variables:You could also use a React ref to cache the current
totalScorestate value and reference this in the handler: