当前位置: 首页 > 面试题库 >

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

衡子安
2023-03-14
问题内容

我正在学习有关如何使用钩子注册事件的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});

将新键入的键追加到当前状态并设置为新状态,但是,它会忘记旧状态并用新状态重写。

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


问题答案:

处理此类情况的最佳方法是查看事件处理程序中的操作。如果仅使用先前状态设置状态,则最好使用回调模式并仅在初始安装时注册事件侦听器。如果您不使用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);
    };
  }, [handleUserKeyPress]);

  return (
    <div>
      <h1>Feel free to type!</h1>
      <blockquote>{userText}</blockquote>
    </div>
  );


 类似资料:
  • 如何使用钩子(或任何其他钩子)来复制? 在传统的类组件中,我将执行以下操作: 使用hook: (完整示例:https://codesandbox.io/s/2oo7zqzx1n) 这不起作用,因为在中返回的“cleanup”函数捕获装载期间的道具,而不是卸载期间的道具状态。 如何在不运行函数体(或清除)的情况下对每个道具更改进行清理? 一个类似的问题并没有涉及获得最新道具的部分。 文件状态为: 如

  • 我想在中调用几个异步函数,但我不确定如何包含关键字以等待它们的结果 这给了我 意外的保留字“await” 如何在中异步函数?

  • 我试图创建一个简单的组件,从Apollo GraphQL服务器(查询)返回我的所有组织。我想从一个上下文状态呈现所有这些组织,在这个上下文状态下,在组件挂载(由useEffect挂钩处理)之后,可以使用分派方法放置这些组织。 如果状态结果(organizations数组)为空,useEffect钩子应该调用函数getOrganizations,然后调用自定义钩子useGetOrganization

  • 有人能解释一下我做错了什么吗?我有一个react功能组件,在其中我使用useEffect钩子从服务器获取一些数据,并将这些数据放入状态值。在获取数据之后,在同一个useHook中,我需要使用该状态值,但由于某些原因,该值是明确的。看看我的示例,console有一个空字符串,但在浏览器上我可以看到该值。 链接到codesandbox。

  • 我目前正在写一个wordpress插件,我遇到了一些问题。我的功能在插件激活时不运行。。。谁能告诉我问题出在哪里? 但不幸的是,安装功能不起作用......但当外部类中的代码安装功能是工作

  • 我显示的优惠券的列表基于类别选择使用使用使用效果和佐贺。 这是我的初始状态。设置为真正的默认值,以便每当组件被访问时,它首先显示加载器,之后从获得调度,它命中api并使用redux-saga异步获得响应,然后设置为false,并根据响应或得到更新。 这是一个组件: 当组件第一次被访问时,正在加载因此将变为真,并且组件呈现加载程序并请求api获取数据。 从api获取数据后,加载设置为false,组件