我正在学习一门关于如何用挂钩注册事件的 Udemy 课程,讲师给出了以下代码:
const [userText, setUserText] = useState('');
const handleUserKeyPress = event => {
const { key, keyCode } = event;
if (keyCode === 32 || (keyCode >= 65 && keyCode <= 90)) {
setUserText(`${userText}${key}`);
}
};
useEffect(() => {
window.addEventListener('keydown', handleUserKeyPress);
return () => {
window.removeEventListener('keydown', handleUserKeyPress);
};
});
return (
<div>
<h1>Feel free to type!</h1>
<blockquote>{userText}</blockquote>
</div>
);
现在它工作得很好,但我不相信这是正确的方式。原因是,如果我理解正确的话,在每一次重新呈现时,事件都会继续注册和注销,我只是不认为这是正确的做法。
所以我对 useEffect
挂钩做了一个小小的修改
useEffect(() => {
window.addEventListener('keydown', handleUserKeyPress);
return () => {
window.removeEventListener('keydown', handleUserKeyPress);
};
}, []);
通过将一个空数组作为第二个参数,使组件只运行一次效果,模仿 componentDidMount
。当我试验结果时,奇怪的是,我键入的每个键,不是附加,而是覆盖。
我原以为 SetUserText (${userText}${key}
) ;会在当前状态后添加新类型的键,并将其设置为新状态,但实际上它忘记了旧状态并用新状态重写。
我们应该在每次重新呈现时注册和注销事件,这真的是正确的方法吗?