0

I have an input control in a form. I use setState to assign it to a variable (inputValue). It's being properly changed - {inputValue} shows the changing value as I type.

When I try to use the value in a key handler, the key handler sees a stale version of the variable that doesn't change on keystrokes. What is going on and how do I fix it?

Code to reproduce problem. I'm using NextJS / Typescript annotations:

import { NextPage } from 'next';
import { useState, useEffect } from 'react';

const Keypress_Problem: NextPage<{ }> = ( ) =>
{
    const [inputValue, setInputValue] = useState('');

    const upHandler = ({key}: {key: string}) => {
        console.log(key + ';' + inputValue ); // <<< inputValue doesn't change -- what is happening here??
      };

    useEffect(() => {
        window.addEventListener("keyup", upHandler);
        return () => {window.removeEventListener("keyup", upHandler);};}, []);

    return (
        <>
            <input type="text" value={inputValue} 
                onChange={(e: React.ChangeEvent<HTMLInputElement>) => {setInputValue(e.target.value);}} />

            <br/>
            InputValue:{inputValue} 

        </>
    );
};

export default Keypress_Problem;    
Greg Sherman
  • 1,084
  • 1
  • 11
  • 22

1 Answers1

1

You have created the listener on an initial load inside useEffect and hence the upHandler function will only be having the initial value of state inputValue due to closure.

You could add inputValue as a dependency to useEffect to get around the closure problem

const upHandler = ({key}: {key: string}) => {
    console.log(key + ';' + inputValue ); // <<< inputValue doesn't change -- what is happening here??
  };

useEffect(() => {
    window.addEventListener("keyup", upHandler);
    return () => {
        window.removeEventListener("keyup", upHandler);
    };
 }, [inputValue]);
Shubham Khatri
  • 270,417
  • 55
  • 406
  • 400