Created
September 20, 2022 06:54
-
-
Save raphaelsetin/b1f6a67b662ee07b8a30299aa0185d3d to your computer and use it in GitHub Desktop.
Detect Multiple Pressed Keys in React / JavaScript
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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