Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

238
Visualizações
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 Respostas
Responde à pergunta

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda