Home > Enterprise >  using a keypress eventlistenner on the entire document causes multi-renders after a few uses
using a keypress eventlistenner on the entire document causes multi-renders after a few uses

Time:10-01

I'm using a provider for my entire app, and I need to create an event when the r key is pressed, it runs a func, this context works inside the buttons, but with the event listenner it duplicates itself, causing the app to crash

I thought of creating inside the app with a useEffect with an empty dependency array, that is, a componentDidMount, but I don't have access to the context there before exposing it to the application

AppContextProvider...

  // Sample Hand generator
  const [sample, setSample] = useState<[]>([]);
  const generateNewHand = () => {
    if (database.length > 0) {
      const rand = Math.floor(Math.random() * database.length);
      const newHand = database[rand];
      setSample(newHand);
      console.log("[generateNewHand] ", newHand);
    }
  };

  // -----------------------------------------

  document.addEventListener(
    "keypress",
    ({ key }) => key == "r" && generateNewHand()
  );

  return (
    <AppContext.Provider
      value={{ ready, setReady, openFile, sample, generateNewHand }}
    >
      {children}
    </AppContext.Provider>
  );

working element example..

<GiCardPickup onClick={generateNewHand} />

console after a few uses of keypress 'r' enter image description here

CodePudding user response:

Operations like that should be used inside useEffect hook because you add a new listener every render.

useEffect(() => {
  const fn = ({ key }) => key == "r" && generateNewHand()
  document.addEventListener(
    "keypress",
    fn
  );
  return () => document.removeEventListener('keypress', fn) 
}, [])
  • Related