score:2

Accepted answer

issue

you are enclosing the initial state in the attached callback by only setting the callback when the component mounts using an empty dependency array. a functional state update won't have this issue as it uses a callback function to compute and return a new state value from the previous state value.

solution

  • the effect needs to add an event listener correctly. (and return a cleanup function!!)
  • state update should be a functional update since it depends on previous state.
  • state updates are asynchronous in nature, so alerting or logging it right after it is enqueued will only log the current state value from the current render cycle. use an effect to do anything with the updated state.

updated code

const hello = () => {
  const [counter, setcounter] = react.usestate(0);
  let canvas = react.useref();

  const add = () => {
    setcounter(counter => counter + 3);
  };

  react.useeffect(() => {
    console.log(counter); // or alert, if you really want to
  }, [counter]);

  react.useeffect(() => {
    window.addeventlistener("keydown", add);
    return () => window.removeeventlistener("keydown", add);
  }, []);

  return (
    <div>
      <h1>{counter}</h1>
    </div>
  );
};

edit add window event listener

score:0

passing an empty array will trigger the useeffect only at the mounting of the component, just add the counter in the array in order for it to be triggered every time the state is updated.

  react.useeffect(() => {
    window.onkeydown = add
  }, [counter])


Related Query

More Query from same tag