[英]How to catch keydown event inside child component
There is a component that catches keyDown event.有一个组件可以捕获 keyDown 事件。 It has a counter which is incremented by Arrow Right and decremented by Arrow Left.它有一个计数器,按向右箭头递增,按向左箭头递减。
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>
);
}
It works fine.它工作正常。
Now, there is a child component that has an input field.现在,有一个具有输入字段的子组件。 I would like it to catch arrow left and arrow right so it IS NOT propagated to the main component.我希望它能捕捉到左箭头和右箭头,这样它就不会传播到主要组件。 My guess was:我的猜测是:
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" />;
}
But it does not seem to work.但这似乎不起作用。 The child receives the event AND the parent receives the event as well.孩子收到事件,父母也收到事件。 I guess the problem is that the event handler is linked to the window.document, but how do I change it?我想问题是事件处理程序链接到 window.document,但我该如何更改它?
Here is the codesandbox example: https://codesandbox.io/s/bold-pare-fvd305这是 codesandbox 示例: https://codesandbox.io/s/bold-pare-fvd305
Thank you in advance!先感谢您!
You can ignore the keyDown if it was made inside the input field.如果 keyDown 是在输入字段内创建的,则可以忽略它。 You just need to check event.target :你只需要检查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.