Reputation: 29
I'm building a piano that display some css
style when user "press" some keyboard button (keydown
) ( click multiples
different button at the same time also allow). When user stop pressing (keyup
) , simply remove those css
style .
Ex: click and hold "A", "B", "C" will add active class to them , release "C" only remove active class to "C".
I plan to do it with react hook like this :
const [press, setPress] = useState([]); //Hook state
// store the keyboard user click into an array
const keyDown = (e) => {
if (e.repeat) {
return;
}
setPress((oldArr) => [...oldArr, e.key]);
};
// remove only the one that user release
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);
};
}, []);
//just pass the press arr to child element
return (
<div className="main">
<Child press={press} />
</div>
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
The keydown
event work's fine , but the keyup
keep reset
the press
array back to empty . I don't understand why this work like this . Can someone explain it for me ? Thank in advance
Upvotes: 0
Views: 1425
Reputation: 52
changing the key up filter works for me
const keyRemove = press.filter(function(value, index, arr){
return value !== e.key;
});
Upvotes: 0
Reputation: 12787
I think the problem is your logic in keyUp
. You need to update the filter
:
const keyUp = (e) => {
setPress(press.filter((key) => key !== e.key));
};
Upvotes: 2