为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

蝴蝶不菲 2021-04-09 14:11:13
我正在学习有关如何使用钩子注册事件的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}); 将新键入的键追加到当前状态并设置为新状态,但是,它会忘记旧状态并使用新状态进行重写。我们应该在每次重新渲染时注册和注销事件真的是正确的方法吗?
查看完整描述

3 回答

?
慕的地6264312

TA贡献1817条经验 获得超6个赞

新答案:


useEffect(() => {

  function handlekeydownEvent(event) {

    const { key, keyCode } = event;

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

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

    }

  }


  document.addEventListener('keyup', handlekeydownEvent)

  return () => {

    document.removeEventListener('keyup', handlekeydownEvent)

  }

}, [])

使用时setUserText,将函数作为参数而不是对象作为参数传递,prevUserText它将始终是最新状态。


旧答案:


试试看,它的工作原理与您的原始代码相同:


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])

因为在您的useEffect()方法中,它取决于userText变量,但是您不要将其放在第二个参数内,否则,userText将始终将参数绑定到''带有arguments的初始值[]。


您不需要这样做,只想让您知道第二个解决方案为何不起作用。


查看完整回答
反对 回复 2021-04-22
  • 3 回答
  • 0 关注
  • 270 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信