React JS keyDown 侦听器故障

React JS keyDown Listener glitching

在我的代码中我有:

 useEffect(() => {
    window.addEventListener("keydown", handleKeyDown);
  });

这会创建一个事件监听器来监听我的键盘。然后在我的 handleKeyDown 上我有:

const [keys, setKeys] = useState([]);

  const handleKeyDown = (event) => {
    console.log(event.key);
    if (event.repeat) {
      return;
    }

    const key = event.key;
    if (!keys.includes(key)) {
      let updatedPressedKeys = [...keys];
      updatedPressedKeys.push(key);
      setKeys(updatedPressedKeys);
    } else {
      return;
    }
  };

基本上,我有一个 keys 数组变量。我想将按下的每个唯一键添加到 keys 变量上。所以我首先检查用户是否按住了键。然后我检查当前按下的键是否在 keys 中,如果不是我将它添加到键中。然而,当我 运行 我的代码时,我第一次按下一个键时, handleKeyDown 方法被调用一次。然后当我松开并按下第二个键时,该方法被调用两次。然后它被调用 4 次,然后是 8 次。最终它需要很长时间并且变得迟钝。我不确定为什么每次都会调用更多次该方法。请让我知道怎么了。参考下面的截图。

每次您的组件呈现时,您都会在 useEffect 中添加一个新的事件侦听器。

useEffect(() => {
  window.addEventListener("keydown", handleKeyDown);
});

您应该添加依赖数组和清理函数。空的依赖数组将作为一个“componentDidMount”效果只添加一次监听器,清理函数作为一个“componentWillUnmount”函数来清理监听器up/remove

useEffect(() => {
  window.addEventListener("keydown", handleKeyDown);

  return () => {
    window.removeEventListener("keydown", handleKeyDown);
  };
}, []);

您可能还想将侦听器回调转换为使用功能状态更新,这样您就不会拥有陈旧的状态外壳。

const [keys, setKeys] = useState([]);

const handleKeyDown = (event) => {
  const { key } = event;

  console.log(key);

  if (event.repeat) {
    return;
  }

  setKeys(keys => {
    if (!keys.includes(key)) {
      return [...keys, key];
    }
    return keys;
  });
};