How to register event with useEffect hooks?

React JS Faysal Shuvo

Problem:

So I am following a youtube tutorial. The instructor showed us how to register event. Then I was practicing. Try to do other way but got my self into problem. This is my code down below:

const [inputTxt, setInputTxt] = useState('');
const userKeyPressHandler = event => {
  const { key, keyCode } = event;
  if (keyCode === 32 || (keyCode >= 65 && keyCode <= 90)) {
    setInputTxt(`${inputTxt}${key}`);
  }
};
useEffect(() => {
    window.addEventListener('keydown', userKeyPressHandler);
    return () => {
      window.removeEventListener('keydown', userKeyPressHandler);
    };
}, []);
return (
  <div>
    <h1>Type Anything:</h1>
    <p>{inputTxt}</p>
  </div>
);

In this article, we will learn how to register event with useEffect hooks?


Solution: 

To set the state using the previous state, it is best to use a callback pattern and on the initial mount register the event listeners.

And if you do not use the callback pattern, the listernes reference along with the lexical scope is being used by the event listener. A new function is created on each render with updated closure.So, in the handler you will not able to access the updated state. This is the correct way to register event with useEffect hook:

const [inputTxt, setInputTxt] = useState("");
const userKeyPressHandler = useCallback(event => {
    const { key, keyCode } = event;
    if(keyCode === 32 || (keyCode >= 65 && keyCode <= 90)){
        setInputTxt(prevUserText => `${prevUserText}${key}`);
    }
}, []);
useEffect(() => {
    window.addEventListener("keydown", userKeyPressHandler);
    return () => {
        window.removeEventListener("keydown", userKeyPressHandler);
    };
}, [userKeyPressHandler]);
return (
      <div>
          <h1>Type Anything:</h1>
          <p>{inputTxt}</p>
      </div>
);

Thank you for reading this article. If you have any problem comment down below