1

So i'm trying to make a card guessing game and I need to set state multiple times in one clickHandler, but everytime it just uses the previous state because state is asynchronous and it doesn't have enough time to update. How can I achieve something similar to async await in this event handler? SetGame is my setState.

const clickHandler = (e) => {
  let copy = [...game.pictures];
  shuffle(copy);
  setGame((prevState) => {
    return { ...prevState, pictures: copy };
  });

  let clickedId = [...game.clickedPics];

  if (!clickedId.includes(e.target.id)) {
    setGame((prevState) => {
      return { ...prevState, currentScore: game.currentScore + 1 };
    });

    if (game.highScore < game.currentScore) {
      setGame((prevState) => {
        return { ...prevState, highScore: game.currentScore };
      });
    }

    clickedId.push(e.target.id);
    setGame((prevState) => {
      return { ...prevState, clickedPics: clickedId };
    });
    console.log(game.clickedPics);
  } else {
    setGame((prevState) => {
      return { ...prevState, currentScore: 0 };
    });
    clickedId = [];
    setGame((prevState) => {
      return { ...prevState, clickedPics: clickedId };
    });
  }
};

1 Answer 1

2

Since, as you said, setState is an async operation, you have to create your state object and only setGame once in the end. Try this:

  let copy = [...game.pictures];
  const stateCopy = { ...game } // or whatever name your state is here
  shuffle(copy);
  stateCopy.pictures = copy;

  let clickedId = [...game.clickedPics];

  if (!clickedId.includes(e.target.id)) {
    stateCopy.currentScore = game.currentScore + 1;

    if (game.highScore < game.currentScore) {
      stateCopy.highScore = game.currentScore;
    }

    clickedId.push(e.target.id);
    stateCopy.clickedPics = clickedId;
    console.log(game.clickedPics);
  } else {
    stateCopy.currentScore = 0;
    clickedId = [];
    stateCopy.clickedPics = clickedId;
  }

  setGame(stateCopy);
};
Sign up to request clarification or add additional context in comments.

1 Comment

This is exactly what I was looking for! Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.