Skip to content

Instantly share code, notes, and snippets.

@raphaelsetin
Created September 20, 2022 06:54
Show Gist options
  • Save raphaelsetin/b1f6a67b662ee07b8a30299aa0185d3d to your computer and use it in GitHub Desktop.
Save raphaelsetin/b1f6a67b662ee07b8a30299aa0185d3d to your computer and use it in GitHub Desktop.
Detect Multiple Pressed Keys in React / JavaScript
import { useEffect, useState } from "react";
import Backdrop from '@mui/material/Backdrop';
export const Example = () => {
const [backdropOpen, setBackdropOpen] = useState(false);
useEffect(() => {
// Keys that need to be pressed at the same time in order for
// the 'backdropOpen' variable to be 'true'
const keysArr = ['ControlLeft', 'ShiftLeft', 'AltLeft'];
const keysMap = {};
let backdropOpenLocal = false;
const keydownEvent = 'keydown';
const keyupEvent = 'keyup';
const checkKeys = () => {
const keysArePressed = keysArr.every((value) => keysMap[value] === keydownEvent);
if (keysArePressed !== backdropOpenLocal) {
backdropOpenLocal = keysArePressed;
setBackdropOpen(keysArePressed);
}
}
const handleKeyDown = (event) => {
const keyCode = event.code;
if (keysArr.includes(keyCode) && keysMap[keyCode] !== keydownEvent) {
keysMap[keyCode] = keydownEvent;
}
checkKeys();
}
const handleKeyUp = (event) => {
const keyCode = event.code;
if (keysArr.includes(keyCode) && keysMap[keyCode] !== keyupEvent) {
keysMap[keyCode] = keyupEvent;
}
checkKeys();
}
document.addEventListener('keydown', handleKeyDown);
document.addEventListener('keyup', handleKeyUp);
return () => {
document.removeEventListener('keydown', handleKeyDown);
document.removeEventListener('keyup', handleKeyUp);
}
}, []);
return (
<React.Fragmemnt>
<div>
<Backdrop
open={backdropOpen}
>
<span>
It worked!
</span>
</Backdrop>
</div>
</React.Fragmemnt>
);
}
/*
Keep in mind that we need to use the `backdropOpenLocal` instead of `backdropOpen`
inside the `useEffect` function, because we want to update the local scoped variable
only and keep the state of the scope.
If we update the state of the Example component and try to access `backdropOpen`,
we will have the same value as before, unless we pass in the `backdropOpen` in
the dependency array of `useEffect`; this would cause the scoped variables inside
`useEffect` to be reset, and we don't want that.
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment