React keydown事件监听器被多次调用?

时间:2020-10-19 20:14:43

标签: reactjs

所以我做了这个模态https://codesandbox.io/s/amazing-morning-ukxp2?file=/src/components/Modal.js

每当您按Esc键时,都应该关闭模态。我添加了一条消息,每次按ESC时都会显示。

但是,如果您检查控制台,它每次都会以2倍的倍数打印我的消息,因此过一会儿,它将说出100次消息

这是我指的功能

           function keyPress(e) {
        if (e.key === 'Escape' && showModal) {
          setShowModal(false);
          console.log('I pressed');
        }
      }

      document.addEventListener('keydown', keyPress);

我试图将其放入useEffect函数中,并将showModal添加为依赖项,但是我无法使其正常工作

当我只希望在模式打开时和一次按esc键时才触发keydown事件侦听器时,如何防止它在控制台中显示太多次?

似乎每次我重新打开模式时,它都会使esc键消息加倍。

1 个答案:

答案 0 :(得分:1)

您需要在useEffect钩子内处理事件监听器(添加,删除):

useEffect(() => {
  document.addEventListener("keydown", keyPress);
  return () => document.removeEventListener("keydown", keyPress);
});

这样,您将在每个生命周期中订阅keyPress函数。 为了进一步改善它,您可以将keyPress包装在useCallback钩子中(以在新的渲染器中记住该函数)并将其添加为依赖项:

  const keyPress = useCallback(
    (e) => {
      if (e.key === "Escape" && showModal) {
        setShowModal(false);
        console.log("I pressed");
      }
    },
    [setShowModal, showModal]
  );

  useEffect(() => {
    document.addEventListener("keydown", keyPress);
    return () => document.removeEventListener("keydown", keyPress);
  }, [keyPress]);

Modified codesandbox