Bharat Soni
Bharat Soni

Reputation: 2902

React component is picking the old state when used with hooks

I'm still getting a hang of hooks in React. I am making a tic tac toe game to understand the concept of the useState hook. Everything works fine but I need to make an extra move to find the winner. This is because I'm calling a function on every user move, and that function is unable to get the updated state, it always has one step older state of the game.

Here is the link to the CodeSandbox. Here is how the flow works:

Observe that the console in the selectSquare function has the stale state even when the updateSquares was executed. I was expecting that the state would be updated function was called.

As requested in the comments, I'm adding the relevant part of the code here:

function useBoardState() {
  const [squares, setSquares] = useState(() => Array(9).fill(null));

  function updateSquares(index, mark) {
    setSquares((prevSquares) => {
      const newSquares = [...prevSquares];

      newSquares[index] = mark;

      return newSquares;
    });
  }

  return [squares, updateSquares];
}

I think it has something to do with this custom hook, I think the updateSquares state dispatcher updates the state when the render is complete.

not sure what am I missing here.

Upvotes: 0

Views: 2134

Answers (1)

Jonas Grønbek
Jonas Grønbek

Reputation: 2019

the setter returned from useState as well as the class based component equivelant setState are not called synchronously. That is why if you do something like

const updateSomething = () => {
   setFoo(1)
   setBar(2)
   setFooBar(3)
   console.log('hey')
}

React will log hey before it starts setting the state, furthermore it will actually batch setFoo, setBar and setFooBar together, so it does a single rerender with all the above state updates.

Upvotes: 1

Related Questions