Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

226
Vistas
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 Respuestas
Responde la pregunta

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda