如何使用useEffect挂钩注册事件?

我正在学习有关如何使用钩子注册事件的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}); 将新键入的键追加到当前状态并设置为新状态,但是,它会忘记旧状态并使用新状态进行重写。


我们应该在每次重新渲染时注册和注销事件真的是正确的方法吗?


蝴蝶不菲
浏览 271回答 3
3回答

慕的地6264312

新答案:useEffect(() => {&nbsp; function handlekeydownEvent(event) {&nbsp; &nbsp; const { key, keyCode } = event;&nbsp; &nbsp; if (keyCode === 32 || (keyCode >= 65 && keyCode <= 90)) {&nbsp; &nbsp; &nbsp; setUserText(prevUserText => `${prevUserText}${key}`);&nbsp; &nbsp; }&nbsp; }&nbsp; document.addEventListener('keyup', handlekeydownEvent)&nbsp; return () => {&nbsp; &nbsp; document.removeEventListener('keyup', handlekeydownEvent)&nbsp; }}, [])使用时setUserText,将函数作为参数而不是对象作为参数传递,prevUserText它将始终是最新状态。旧答案:试试看,它的工作原理与您的原始代码相同:useEffect(() => {&nbsp; function handlekeydownEvent(event) {&nbsp; &nbsp; const { key, keyCode } = event;&nbsp; &nbsp; if (keyCode === 32 || (keyCode >= 65 && keyCode <= 90)) {&nbsp; &nbsp; &nbsp; setUserText(`${userText}${key}`);&nbsp; &nbsp; }&nbsp; }&nbsp; document.addEventListener('keyup', handlekeydownEvent)&nbsp; return () => {&nbsp; &nbsp; document.removeEventListener('keyup', handlekeydownEvent)&nbsp; }}, [userText])因为在您的useEffect()方法中,它取决于userText变量,但是您不要将其放在第二个参数内,否则,userText将始终将参数绑定到''带有arguments的初始值[]。您不需要这样做,只想让您知道第二个解决方案为何不起作用。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript