grififth
grififth

Reputation: 13

React useState is working on one state but not the other

I'm currently trying to make a wordle style game with react.

In my main component, I have a useEffect that runs once to initialize some things as well as creating a "keydown" eventListener.

  useEffect(() => {
    //These two functions getWordList and updateColors don't really matter much for this issue I think.
    const getWordList = async () => {
      let response = await fetch(wordListUrl);

      var wordList = await response.text();

      var wordListArr = wordList.split("\n");

      setWords(wordListArr);

      const randomWord =
        wordListArr[Math.floor(Math.random() * wordListArr.length)];

      setAnswer(randomWord);
    };

    const updateColors = async () => {
      const newColors = {} as any;

      for (let c of alphabet) {
        newColors[c] = "bg-gray-400";
      }

      setColors(newColors);
    };

    //THIS FUNCTION is the one that's probably causing an issue.

    const setupKeys = async () => {
      document.addEventListener("keydown", logKey);

      function logKey(e: any) {
        if (e.code.match(/Key[A-Z]/)) {
          handleInput(e.code[3].toLowerCase());
        }
        if (e.code == "Enter" || e.code == "Backspace") {
          handleInput(e.code);
        }
      }
    };

    getWordList();
    updateColors();
    setupKeys();
  }, []);

I then have my handleInput function written outside of the useEffect but inside the component as follows:

  const handleInput = (keyPress: string) => {
    console.log(keyPress);
    if (keyPress == "Enter") {
      return;
    }

    if (keyPress == "Backspace") {
      return;
    }

    let oldWord = (curWord + keyPress).slice(0, 5);

    setCurWord(oldWord);

    let currentBoard = board;
    currentBoard[curLine] = oldWord;

    while (currentBoard[curLine].length < 5) currentBoard[curLine] += " ";

    setBoard([...currentBoard]);
  };

For some reason when I run this code though, the board is updating on my keypresses but the curWord state is never stored. What I mean is that when I console.log curWord, it's always the empty string it's initialized to but the board gets updated appropriately. I'm not sure why the board is being updated but the word isn't.

I've tried messing around with useCallback but none of it has worked.

Some help would be really appreciated.

Upvotes: 1

Views: 163

Answers (1)

Your event handler function has the closure of the first render. That means the state inside the handler is always the same. You should update the event handler everytime the state changes. To do that, create a new useefect that changes the keypress event handler with the state in the dependency array.

Upvotes: 1

Related Questions