How can and where should I add an onKeyDown event Listener for my "Save Employee" button in ReactJS?

201 Views Asked by At

screen capture CodeSandbox Repo

I would like to listen to keyDown events, specifically, the key S so users can easily save a randomly generated employee conveniently instead of clicking the Save Employee button multiple times.

In JavaScript, I would add the event on the document body like, document.body.addEventListener('keydown'), but in React I don't know where to place the event. For now, I added it inside the index.js file like: onKeyDown={handleKeyDown}

I commented out my failed attempt (check image, code repo, or snippet below).

function SaveEmployee({ ...props }) {
  const [employees, setEmployees] = useState([]);

  const displayEmployee = () => {
    setEmployees((current) => [...current, { ...props }]);
  };


  // const displayEmployee = (event) => {
  //   if (event.key === "KeyS") { setEmployees((current) => [...current, { ...props }]);
  //   } else  { console.log('do nothing');    }
  // };

return (
    <>
      <div>
        <button title="Save new random employee data" onClick={displayEmployee}>
          Save Employee
        </button>
      </div>
      ...
  1. The keyCode property is deprecated so I tried the event.key but no luck yet.
  2. I also tried creating a separate component KeyDownEvents.js to see if splitting the code from SaveEmployee.js would fix the issue and to see if it works like document.body.addEventListener, since Index.js is the main component that houses all children components, but no luck. KeyDownEvents.js file and Index.js
2

There are 2 best solutions below

2
Cody Duong On

onClick is for handling mouse events. You want to use onKeyPress (or onKeyUp or onKeyDown. Read Q/A: onKeyPress Vs. onKeyUp and onKeyDown).

The event.key for "S" is not "KeyS", it is simply "s" (or "S" if you want it to be shift+s)

export default function SaveEmployee(props) {
  const [employees, setEmployees] = useState([]);

  const displayEmployee = () => {
    console.log('mouse click');
    setEmployees((current) => [...current, { ...props }]);
  };

  const displayEmployeeKeyPress = (event) => {
    if (event.key === "s") {
      console.log("key click");
      setEmployees((current) => [...current, { ...props }]);
    } else {
      console.log("do nothing");
    }
  };

  return (
    <>
      <div>
        <button
          title="Save new random employee data"
          onClick={displayEmployee}
          onKeyPress={displayEmployeeKeyPress}
        >
          Save Employee
        </button>
      </div>
    </>
  );
}

NOTE: that this event only fires if you have the <button> in focus.

View on CodeSandbox

1
Chakib Salah On
  • There is problem with the event name , on the code sand box you are listening to an event named onClick which is wrong .

onCLick: There no event named like this . ( true you can handle events on the react element with onClick={someFunction} , but events with using element.addEventListener(event) are not named like that )

click: Mouse click event .

keydown: Keyboard click down event .

  • Solution would be
  /*  useEffect  */

  const handleClick = (event) => {
    if (event.key === "s") {
      console.log("yay s");
    }
    if (event.key === "S") {
      console.log("yay capital s");
    }
  }; // You might also want to move this function outside useEffect

  useEffect((props) => {
    // before ==> window.addEventListener("onClick", handleClick);
    window.addEventListener("keydown", handleClick);
  }, []);