javascript - javascript - 如何使用useEffect钩子注册事件?

  显示原文与译文双语对照的内容

我正在遵循一个Udemy课程,关于如何使用钩子进行 register 事件,教师给了 below 代码:


 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>


 );



现在效果不错,但我不认为这是正确的方法。 原因是,如果我正确地理解每个 and,事件将每次都注册和删除,我不认为这是正确的方法。

所以我对 useEffect 钩子做了一点修改


useEffect(() => {


 window.addEventListener('keydown', handleUserKeyPress);



 return () => {


 window.removeEventListener('keydown', handleUserKeyPress);


 };


}, []);



使用一个空的array 作为第二个参数,让组件只运行一次效果,模仿 componentDidMount 。 而当我尝试结果时,对于每个键i 类型而言,它是非常奇怪的,而不是被覆盖。

在当前状态和设置为新状态的情况下,会有新的键入键附加到当前状态,但它会忘记旧状态并用新状态重写。

是否真的是我们在每次渲染时都应该对事件进行 register 和取消注册的正确方法?

时间:

解决这种情况的最佳方法是查看事件处理程序中所做的事情。 如果只是使用以前状态设置状态,最好使用回调 Pattern,而只在初始挂载时使用事件监听器。 如果不使用 callback pattern ( https://reactjs.org/docs/hooks-reference.html#usecallback ),事件侦听器将使用侦听器引用,但新的函数中创建了新的函数。


const [userText, setUserText] = useState('');



 const handleUserKeyPress = useCallback(event => {


 const { key, keyCode } = event;



 if (keyCode === 32 || (keyCode> = 65 && keyCode <= 90)) {


 setUserText(prevUserText => `${prevUserText}${key}`);


 }


 }, []);



 useEffect(() => {


 window.addEventListener('keydown', handleUserKeyPress);



 return () => {


 window.removeEventListener('keydown', handleUserKeyPress);


 };


 }, []);



 return (


 <div>


 <h1>Feel free to type!</h1>


 <blockquote>{userText}</blockquote>


 </div>


 );



试试这个,它与你的原始代码相同:


useEffect(() => {


 function handlekeydownEvent(event) {


 const { key, keyCode } = event;


 if (keyCode === 32 || (keyCode> = 65 && keyCode <= 90)) {


 setUserText(`${userText}${key}`);


 }


 }



 document.addEventListener('keyup', handlekeydownEvent)


 return () => {


 document.removeEventListener('keyup', handlekeydownEvent)


 }


}, [userText])



because的方法是依赖于 userText 变量,但是不把它放入第二个参数,否则 userText 总是被绑定到初始值 '' 中,用参数 [] 表示。

你不需要这样做,只是想让你知道为什么你的第二个解决方案不能工作。

对于你的用例,useEffect 需要一个依赖项 array 来跟踪更改,并根据它可以确定是否呈现。 始终建议将依赖项 array 传递给 useEffect 。 请参见代码 below:

我已经介绍了 useCallback hook 。


const { useCallback, useState, useEffect } = React;



function App() {


 const [userText, setUserText] = useState('');



 const handleUserKeyPress = useCallback(event => {


 const { key, keyCode } = event;



 if (keyCode === 32 || (keyCode> = 65 && keyCode <= 90)) {


 setUserText(`${userText}${key}`);


 }


 }, [userText]);



 useEffect(() => {


 window.addEventListener('keydown', handleUserKeyPress);



 return () => {


 window.removeEventListener('keydown', handleUserKeyPress);


 };


 }, [handleUserKeyPress]);



 return (


 <div>


 <blockquote>{userText}</blockquote>


 </div>


 );


}



Edit q98jov5kvq

...