Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

233
Views
State won't change in "keydown" event in React

I am making a an app where I need to register the keys the user presses. To do that I am using keydown and keyup events. However, I don't want to register the same key multiple times when the user holds it down.

I want to make it so the downHandler function won't run multiple times whenever you hold down a key. I only want it to run once. I try to use an if statement for that and setting keyPressed to true so it won't run again. I try to log keyPressed right after I set it to true, but it logs as false, and the function still runs again.

I tried to remove setKeyPressed(false) in the downHandler function, but keyPressed was still false no matter what.

Here is my app.js:

import { useState, useEffect } from "react";


function App() {
  const key = useKeyPress();

  function useKeyPress(targetKey) {

    const [keyPressed, setKeyPressed] = useState(false);

    function downHandler(key) {
      if (keyPressed === false) {
        setKeyPressed(true);
        console.log(keyPressed)
      }
    }

    const upHandler = (key) => {
      console.log("up")
      setKeyPressed(false);
    };

    useEffect(() => {
      window.addEventListener("keydown", downHandler);
      window.addEventListener("keyup", upHandler);

      return () => {
        window.removeEventListener("keydown", downHandler);
        window.removeEventListener("keyup", upHandler);
      };
    }, []);
    return keyPressed;
  }

  return (
    <div>

    </div>
  )
}

export default App;
about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

The custom hook should be created in outer scope, when you writing it in the render function (function component body) you are recreating the hook on every render. Hence you losing state each time.

Surprised that you didn't get any lint warning of breaking the rules of hook - writing a hook inside a function, make sure its configured.

Moreover, you are making comparison with stale state keyPressed === false duo to closures, you can fix it by using a reference.

function useKeyPress(targetKey) {
  const [keyPressed, setKeyPressed] = useState(false);

  const keyPressedRef = useRef();

  useEffect(() => {
    keyPressedRef.current = keyPressed;
    console.log("keyPressed", keyPressed);
  }, [keyPressed]);

  useEffect(() => {
    function downHandler(key) {
      if (keyPressedRef.current === false) {
        setKeyPressed(true);
      }
    }

    const upHandler = (key) => {
      setKeyPressed(false);
    };

    window.addEventListener("keydown", downHandler);
    window.addEventListener("keyup", upHandler);

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

  return keyPressed;
}

export default function App() {
  const key = useKeyPress();

  return <div></div>;
}

https://codesandbox.io/s/inspiring-jasper-3lym7p?file=/src/App.js:77-897

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!