У меня есть компонент, который должен прослушивать несколько событий нажатия клавиш.
const [activeKeys, setActiveKeys] = useState([]);
const onKeyDown = e => {
if (!activeKeys.includes(e.key)) {
console.log("keydown", e.key);
setActiveKeys([...activeKeys, e.key]);
}
};
const onKeyUp = e => {
console.log("keyup", e.key);
setActiveKeys([...activeKeys].filter(i => i !== e.key));
};
useEffect(() => {
document.addEventListener("keydown", onKeyDown);
document.addEventListener("keyup", onKeyUp);
return () => {
document.removeEventListener("keydown", onKeyDown);
document.removeEventListener("keyup", onKeyUp);
};
});
в основе.весь код можно найти здесь (codesandbox)
, но он работает нормально 90% времени, однако:
, когда 2 клавиши отпускаются точнов то же время состояние не обновляется дважды.
(Вы можете попытаться воспроизвести его в представленной выше кодовой ячейке, одновременно нажмите любые 2 клавиши, а затем отпустите их в одно и то же время.несколько попыток понять, вот гиф проблемы, происходящей и вот как это выглядит (число - это количество нажатых клавиш, а 's' - это клавиша, которая предположительно нажата внизтем не менее, вы можете видеть, что в журнале консоли был зарегистрирован ключ 's'.) ![screenshot of bug](https://i.stack.imgur.com/MtEiQ.png)
Кто-нибудь сталкивался с чем-то подобным раньше?проблема не в
прослушивателе событий (console.log запускается)
повторного рендеринга (вы можете попробовать нажать некоторые другие клавиши,ключ останется в массиве)
Вот почему я предполагаю, что проблема заключается в крючке, однако я не могу объяснить, почему это происходит.