Как я могу установить состояние несколько раз в одной функции?

#javascript #reactjs

Вопрос:

Поэтому я пытаюсь сделать карточную игру в угадайку, и мне нужно несколько раз установить состояние в одном манипуляторе, но каждый раз он просто использует предыдущее состояние, потому что состояние асинхронно и у него недостаточно времени для обновления. Как я могу добиться чего-то похожего на асинхронное ожидание в этом обработчике событий? СетГейм-это мое сетСтейт.

 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:

Поскольку, как вы сказали, setState это асинхронная операция, вы должны создать свой объект состояния и только setGame один раз в конце. Попробуйте это:

   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);
};
 

Комментарии:

1. Это именно то, что я искал! Спасибо!