State returning late value in Click

Asked

Viewed 79 times

-1

I have a code from a memory game where a sequence of numbers is shown, and the user repeats it through a keyboard created. However, the click value is only captured after double clicking. I would like a help to understand.

I used the.log console to visualize

This is the code of the game:

 function Game() {
  const history = useHistory();
  const emptyBoard = ["1", "2", "3", "4", "5", "6", "7", "8", "9"];
  const [round, setRound] = useState(false);
  const [generatesNumbers, SetgeneratesNumbers] = useState([]);
  const [clicks, setClicks] = useState([]);
  const [displayNumber,  setDisplayNumber] = useState("");
  const [score, setScore] = useState(0);
  let randomNumber;

  useEffect(() => {
    delay(1000).then(() => {
      if (!round) {
        randomNumber = Math.floor(Math.random() * 9 + 1);
        SetgeneratesNumbers([...generatesNumbers, randomNumber]);
        setRound(true);
        console.log(clicks, "antes");
        setClicks([]);
      } else {
        showNumbers();
      }
    });
  }, [round]);

  const CompareArraysLength = () => {
    return generatesNumbers.length === clicks.length;
  };

  const CompareArraysContent = () => {
    return JSON.stringify(generatesNumbers) === JSON.stringify(clicks);
  };
  // passar para a pagina

  const showNumbers = async () => {
    for (let i = 0; i < generatesNumbers.length; i++) {
      setDisplayNumber(generatesNumbers[i]);
      await delay(300);
    }
    setDisplayNumber("");
  };

  const delay = (ms) => {
    return new Promise((resolve) => setTimeout(resolve, ms));
  };

  return (
    <>
      <Display>
        <p>{displayNumber}</p>
      </Display>
      <Board>
        {emptyBoard.map((value, index) => (
          <Cell
            key={index}
            onClick={() => {
              setClicks([...clicks, parseInt(value)]);

              console.log(clicks, "depois");
              if (CompareArraysLength()) {
                if (CompareArraysContent()) {
                  setScore(score + 1);
                  setRound(false);
                } else {
                  history.push("/end");
                }
              }
              //}
            }}
          >
            {value}
          </Cell>
        ))}
      </Board>
    </>
  );
}
export default Game;
  • You can post the code of the Cell component?

  • I’m using Styled Components, it’s just a styling

1 answer

1

To explain why this happens, we first have to understand that setState occurs asynchronously, i.e.: When you run the console.log() by clicking the button, the value that will always be shown will be the previous one.

When we mess with the state of React we usually use the hook useEffect to avoid this kind of problems. You can play the code of your function to a useEffect passing the clicks as dependency

useEffect(() => {

  // Sua verificação aqui

}, [clicks]);

Browser other questions tagged

You are not signed in. Login or sign up in order to post.