Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Keydown event not working as same as onClick in React

I am trying to trigger a slider next and previous events on

  • next and previous click or
  • Left and Right Arrow Click

OnClick events are working as expected. But KeyDown handler not working as expected.
It is working fine on first keypress, like incrementing or decrementing by 1.
But after that, it either goes to -1 or +1.

I guess, I am missing some basic concept. Pls guide me where I am missing.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

You can test here:
https://codesandbox.io/embed/zen-goodall-35f17?fontsize=14&hidenavigation=1&theme=dark

import React, {useState, useEffect} from "react"

function App(){
  const [curImage, move] = useState(0);

  const handleKeypress = (e) => {
      console.log("keydown", e.keyCode);
      if (e.keyCode === 37) {
          leftClick();
      } else if (e.keyCode === 39) {
          rightClick();
      }
  };

  /* eslint-disable */
  useEffect(() => {
      document.addEventListener("keydown", handleKeypress);
      return () => document.removeEventListener("keydown", handleKeypress);
  }, []);
  /* eslint-enable */

  function leftClick() {
    move(curImage - 1);
}

function rightClick() {
    move(curImage + 1);
}

  return(
    <>
      <button onClick={leftClick}>prev</button>
      {"   "}
      {curImage}
      {"   "}
      <button onClick={rightClick}>next</button>
    </>
  )

}

export default App;

>Solution :

You can use functional state update to access the previous state and useCallback hook for memoization so that useEffect won’t trigger unnecessarily.

Edit cocky-lake-pfg2l

import React, { useState, useEffect, useCallback } from "react";

function App() {
  const [curr, setCurr] = useState(0);

  const leftClick = useCallback(() => {
    setCurr((prevCurr) => prevCurr - 1);
  }, []);

  const rightClick = useCallback(() => {
    setCurr((prevCurr) => prevCurr + 1);
  }, []);

  const handleKeypress = useCallback(
    (e) => {
      if (e.keyCode === 37) {
        leftClick();
      } else if (e.keyCode === 39) {
        rightClick();
      }
    },
    [leftClick, rightClick]
  );

  useEffect(() => {
    document.addEventListener("keydown", handleKeypress);
    return () => document.removeEventListener("keydown", handleKeypress);
  }, [handleKeypress]);

  return (
    <>
      <button onClick={leftClick}>prev</button>
      {"   "}
      {curr}
      {"   "}
      <button onClick={rightClick}>next</button>
    </>
  );
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading