As I am in the process of constructing a piano, I want it to showcase certain CSS styles when the user "presses" specific keyboard buttons (via keydown event) - even enabling the simultaneous clicking of multiple different buttons. Once the user releases the keys (using keyup event), the corresponding CSS styles should be removed.
For example, holding down the "A", "B", and "C" keys will add an active class to each of them, whereas releasing just the "C" key would remove the active class from that particular key.
I intend to achieve this using a react hook implementation like so:
const [press, setPress] = useState([]); // Hook state
// Store the user's keyboard clicks in an array
const keyDown = (e) => {
if (e.repeat) {
return;
}
setPress((oldArr) => [...oldArr, e.key]);
};
// Remove only the released key
const keyUp = (e) => {
const keyRemove = press.filter((key) => key !== e.key);
setPress(keyRemove);
};
// Add key press event listener
useEffect(() => {
window.addEventListener("keydown", keyDown);
window.addEventListener("keyup", keyUp);
return function cleanup() {
window.removeEventListener("keydown", keyDown);
window.removeEventListener("keyup", keyUp);
};
}, []);
// Pass the press array to child element
return (
<div className="main">
<Child press={press} />
</div>
);
The keydown event is functioning correctly, but the keyup event keeps resetting the press array back to empty. I'm puzzled about why this behavior occurs in this manner. Could someone please provide an explanation? Thank you in advance!