[英]What is the correct way to handle a key event using useEffect() hook which on the other hand triggers local state changes?
Pretty new to React Hooks and I ran into this issue. React Hooks 非常新,我遇到了这个问题。 I have a functional component that takes an input and sends it to the parent component when I hit the enter key (keycode = 13).
我有一个功能组件,当我按下回车键(keycode = 13)时,它接受输入并将其发送到父组件。 The component looks something like this.
该组件看起来像这样。
const SearchTermBar = (props) => {
const {resetStateSearchTerm, handlePowerToggleParent} = props;
const [inputTerm, handleInputChange] = useState('');
const inputRef = useRef();
useEffect(() => {
const keyPressEvent = (e) => {
if (e.keyCode === 13) {
resetStateSearchTerm(inputTerm);
handleInputChange('');
handlePowerToggleParent('search');
}
};
inputRef.current.addEventListener('keydown', keyPressEvent);
let parentInputRef = inputRef;
return () => {
console.log('remove event listener');
parentInputRef.current.removeEventListener('keydown', keyPressEvent);
}
}, [inputTerm, resetStateSearchTerm, handlePowerToggleParent]);
return (
<div className='SearchTermBar'>
<input
type='text'
placeholder='Enter search term here (Press return to confirm)'
className='SearchTermBar__Input'
value={inputTerm}
onChange={(e) => handleInputChange(e.target.value)}
ref={inputRef}
/>
</div>
);
The problem is that the event is registered and unregistered every time the inputTerm
or props
value changes.问题是每次
inputTerm
或props
值更改时都会注册和取消注册事件。 But I am not able to figure out the correct way to handle the event registration/removal (which should happen once ideally) I understand it is because of the dependency on the inputTerm
but I would like to know a better solution to this problem.但是我无法找出处理事件注册/删除的正确方法(理想情况下应该发生一次)我知道这是因为对
inputTerm
的依赖,但我想知道这个问题的更好解决方案。
You already has the input ref, you don't really need a state:你已经有了输入引用,你真的不需要状态:
const NOP = () => {};
const DEFAULT_INPUT = "";
function SearchTermBar(props) {
const { resetStateSearchTerm = NOP, handlePowerToggleParent = NOP } = props;
const inputRef = useRef();
useEffect(() => {
const keyPressEvent = (e) => {
if (e.keyCode === 13) {
resetStateSearchTerm(inputRef.current.value);
inputRef.current.value = DEFAULT_INPUT;
handlePowerToggleParent("search");
}
};
inputRef.current.addEventListener("keydown", keyPressEvent);
let parentInputRef = inputRef;
return () => {
console.log("remove event listener");
parentInputRef.current.removeEventListener("keydown", keyPressEvent);
};
}, [resetStateSearchTerm, handlePowerToggleParent]);
return (
<input
type="text"
placeholder="Enter search term here (Press return to confirm)"
style={{ width: "50%" }}
ref={inputRef}
/>
);
}
Either way, if you want to keep the state, its value should be duplicated into a ref to fix the closure in the useEffect
.无论哪种方式,如果您想保留状态,应将其值复制到 ref 中以修复
useEffect
的闭包。 It can be done by adding another useEffect
which will update the mentioned ref.这可以通过添加另一个
useEffect
来完成,该useEffect
将更新提到的 ref。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.