繁体   English   中英

如何在子组件中捕获 keydown 事件

[英]How to catch keydown event inside child component

有一个组件可以捕获 keyDown 事件。 它有一个计数器,按向右箭头递增,按向左箭头递减。

export default function App() {
  const [position, setPosition] = React.useState(0);

  // eslint-disable-next-line consistent-return
  React.useEffect(() => {
    const keyboardHandler = (event) => {
      const key = parseInt(event.keyCode || event.which || 0, 10);
      switch (key) {
        case LEFT_ARROW:
          setPosition((p) => p - 1);
          break;
        case RIGHT_ARROW:
          setPosition((p) => p + 1);
          break;
        default:
          break;
      }
    };

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

  return (
    <div className="App">
      {position}
      <br />
      <Inner />
    </div>
  );
}

它工作正常。

现在,有一个具有输入字段的子组件。 我希望它能捕捉到左箭头和右箭头,这样它就不会传播到主要组件。 我的猜测是:

export default function Inner() {
  React.useEffect(() => {
    const keyboardHandler = (event) => {
      const key = parseInt(event.keyCode || event.which || 0, 10);
      switch (key) {
        case LEFT_ARROW:
          event.stopPropagation();
          break;
        case RIGHT_ARROW:
          event.stopPropagation();
          break;
        default:
          break;
      }
    };

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

  return <input name="test" />;
}

但这似乎不起作用。 孩子收到事件,父母也收到事件。 我想问题是事件处理程序链接到 window.document,但我该如何更改它?

这是 codesandbox 示例: https://codesandbox.io/s/bold-pare-fvd305

先感谢您!

如果 keyDown 是在输入字段内创建的,则可以忽略它。 你只需要检查event.target

import "./styles.css";
import React from "react";


const LEFT_ARROW = 37;
const RIGHT_ARROW = 39;

export default function App() {
  const [position, setPosition] = React.useState(0);

  // eslint-disable-next-line consistent-return
  React.useEffect(() => {
    const keyboardHandler = (event) => {
      const key = parseInt(event.keyCode || event.which || 0, 10);
      if (event.target.name !== "test"){
        switch (key) {
          case LEFT_ARROW:
            setPosition((p) => p - 1);
            break;
          case RIGHT_ARROW:
            setPosition((p) => p + 1);
            break;
          default:
            break;
        }
      };
    }
    window.document.addEventListener("keydown", keyboardHandler);
    return () => {
      window.document.removeEventListener("keydown", keyboardHandler);
    };
  }, []);

  return (
    <div className="App">
      {position}
      <br />
      <input name="test" />
    </div>
  );
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM