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

134
Vistas
Increase and decrease the number using addEventListener keydown in React

I wrote a program that adds or subtracts a unit to count by pressing the up and down keys on the keyboard. The problem is that the program does not work properly. When you press the key, look at the console, which runs several times, while each time you press the key, it only has to run once. This is a problem that crashes after pressing the up or down buttons a few times, please help

import React, { useState } from "react";

export default function Example() {
  const [count, setCount] = useState(0);

  document.addEventListener("keydown", function (e) {
    switch (e.keyCode) {
      case 38:
        setCount(count + 1);
        console.log(count);
        break;
      case 40:
        setCount(count - 1);
        console.log(count);
        break;
    }
  });
  return (
    <div>
      <p>You clicked {count} times</p>
    </div>
  );
}
about 4 years ago · Juan Pablo Isaza
3 Respuestas
Responde la pregunta

0

You are adding an event handler every time the component is rendered. The component is re-rendered whenever the state changes. It's an exponential loop, hence your application "crashes".

  • Use useEffect to attach the event listener once the component is mounted and remove it again once the component is unmounted.
  • Provide a callback to setCount to access the current count.
export default function Example() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    const keyDownCallback = function (e) {
      switch (e.keyCode) {
        case 38:
          setCount((count) => count + 1);
          break;
        case 40:
          setCount((count) => count - 1);
          break;
      }
    };

    document.addEventListener("keydown", keyDownCallback);

    return () => document.removeEventListener("keydown", keyDownCallback);
  }, []);

  return (
    <div>
      <p>You clicked {count} times</p>
    </div>
  );
}

See demo

Documentation

  • useEffect
about 4 years ago · Juan Pablo Isaza Denunciar

0

Well each time your component re-renders, it attaches that event listener again and again and calls setCount too many times and re-renders component too many times. Therefore your program falls into infinite loop. I think you should try useEffect and useLayoutEffect hooks.

Edit

import React from "react";

export default function App() {
  const [count, setCount] = React.useState(0);

  const handleUpdateCount = React.useCallback(
    (value) => setCount((prevCount) => prevCount + value),
    [setCount]
  );

  React.useEffect(() => {
    const keyDownCallback = (e) => {
      switch (e.keyCode) {
        case 38:
          handleUpdateCount(1);
          break;
        case 40:
          handleUpdateCount(-1);
          break;
        default:
          console.log("default");
      }
    };

    document.addEventListener("keydown", keyDownCallback);

    return () => document.removeEventListener("keydown", keyDownCallback);
  }, [handleUpdateCount]);

  return (
    <div>
      <p>You clicked {count} times</p>
    </div>
  );
}

In these way, we prevent from extra re-renders.

And about useLayoutEffect, this hook runs given callback after all DOM mutations, But according to official React documentation, We should tend to use useEffect as possible. https://reactjs.org/docs/hooks-reference.html

about 4 years ago · Juan Pablo Isaza Denunciar

0

You have to put document.addEventListener in an useEffect or it will add an event listener each time component re-render

useEffect(() => {
   document.addEventListener("keydown", function (e) {
    switch (e.keyCode) {
      case 38:
        setCount(count + 1);
        console.log(count);
        break;
      case 40:
        setCount(count - 1);
        console.log(count);
        break;
    }
  });
}, [])
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