Pranav Pillai
Pranav Pillai

Reputation: 1373

React Hooks: state not updating when called inside Socket.io handler

const [questionIndex, setQuestionIndex] = useState(0);

...

socket.on('next', () => {
      console.log('hey')
      setQuestionIndex(questionIndex + 1);
});

...


useEffect(() => {
    console.log(questionIndex);
}, [questionIndex]);

I have a page that connects to a websocket using Socket.io. I am attempting to update the value of my questionIndex state variable when I receive a 'next' message from the socket. I seem to be receiving the message because 'hey' is printed, but questionIndex only updates after the first 'hey'. Afterwards, hey is printed, but questionIndex is not (I use the useEffect to print questionIndex when it is updated). Do you guys see anything wrong?

Upvotes: 3

Views: 3087

Answers (3)

Aman kumar
Aman kumar

Reputation: 31

I was also facing this issue. Actually, we should not rely on values from state while updation.

right way to do this is

setQuestionIndex(QuestionIndex=>QuestioIndex+1)

Upvotes: 3

Pranav Pillai
Pranav Pillai

Reputation: 1373

For those wondering, it looks like the socket.on('next') function handler was using the original value of questionIndex (which was 0) every time. It seems like the function handler compiled this variable when it was bound rather than reading it at runtime. Not sure where in the documentation it specifies this behavior.

My solution was to change the function handler as such:

socket.on('next', (newIndex) => {
      console.log('hey')
      setQuestionIndex(newIndex);
});

This solves the problem by providing the value to set questionIndex to (rather than reading it upon receiving a 'next' event).

Upvotes: 3

Gilad Tamam
Gilad Tamam

Reputation: 306

It looks like you open new socket every render and never disconnect it. Try to place socket.on inside useEffect and the return value of that useEffect will be function that disconnect the socket.

useEffect(() => {
  socket.on('next', () => {
    console.log('hey')
    setQuestionIndex(questionIndex + 1);
  });

  return () => socket.disconnect();
}, [questionIndex]);```

Upvotes: 1

Related Questions