1

I have a project where I need to capture all user inputs and concat all characters into a string state variable. My current code can capture all inputs, however the state variable is always one char. Ex: User types "a" and state is set to "A". Then user types "b", and state is set to "B". Intended behavior is state to be set to "AB".

Current code:

const [currentGuess, setCurrentGuess] = useState<string>("");
useEffect(() => {
    const listener = (e: KeyboardEvent) => {
        if (e.code === "Enter") {
            console.log("Pressed enter");
        } else if (e.code === "Backspace") {
            console.log("Pressed backspace");
        } else {
            const key = e.key.toUpperCase();
            if (key.length === 1 && key >= "A" && key <= "Z") {
                setCurrentGuess(`${currentGuess}${key}`);
            }
        }
    };
    window.addEventListener("keyup", listener);
    return () => {
        window.removeEventListener("keyup", listener);
    };
}, []);
lucasz
  • 41
  • 3
  • 1
    This happens because your event listener (created once) only sees the `currentGuess` state as it had been (blank) when it was created. The easiest way around is to add `currentGuess` as a dependency to `useEffect`, but it doesn't seem very efficient. – tromgy Jan 30 '22 at 19:42
  • Does this answer your question? [How to register event with useEffect hooks?](https://stackoverflow.com/questions/55565444/how-to-register-event-with-useeffect-hooks) – pilchard Jan 30 '22 at 22:08

1 Answers1

3

Since currentGuess doesn't change in the listener's scope, just change the set:

...
setCurrentGuess((previousGuess) => `${previousGuess}${key}`);
...

this will allow to use the previously set guess.


More on this here.

Giovanni Londero
  • 1,309
  • 1
  • 10
  • 20