【问题标题】:useEffect unable to invoke function directly?useEffect 无法直接调用函数?
【发布时间】:2020-11-03 14:26:43
【问题描述】:

版本A:useEffect(() => doRequest(), []);

版本B:

useEffect(() => {
  doRequest();
}, []);

我一直认为两个版本完全相同,其中 VersionA 是快捷方式,而 VersionB 允许您在内联函数中执行多个命令。

但是,当我使用 VersionA 时,我正在点击 TypeError: func.apply is not a function,由 NextJS 抛出

如果我使用 VersionB 的语法,一切正常。想知道以前是否有人遇到过这种情况?

更新 我的组件的完整代码

import { useEffect } from 'react';
import useRequest from '../../hooks/use-request';
import Router from 'next/router';

export default () => {
  const { doRequest } = useRequest({
    url: '/api/users/signout',
    method: 'post',
    body: {},
    onSuccess: () => Router.push('/'),
  });

  useEffect(() => doRequest(), []);
  return <div>Signing you out...</div>;
};

【问题讨论】:

  • 我们可以要你的组件代码吗?
  • 这似乎是一个 NextJS 问题,这两种方法虽然语义不同,但不会在 React 中抛出错误。 NextJS 似乎希望您始终在 useEffect 中返回一个函数
  • @ethane 你是怎么得出这个结论的? NextJS 不会篡改 useEffect 所做的事情。

标签: javascript reactjs react-hooks next.js


【解决方案1】:

不完全一样。

useEffect(() => doRequest(), []);

在这种情况下,您的回调将隐式返回 doRequest() 返回的值。 useEffect 回调只能返回一个函数(用于清理效果)或undefined。如果doRequest 不返回任何内容(即undefined)或清理函数,则可以使用该语法。

编辑:正如@3limin4t0r 所指出的,() =&gt; fn()() =&gt; { return fn(); } 相同:

useEffect(() => {
  doRequest();
}, []);

通过拥有一个函数体并且不显式返回某些内容,您的函数会隐式返回 undefined,如果没有要清理的内容就可以了。

【讨论】:

  • @Isaac 你知道提供给useEffect 的函数可以选择返回一个清理函数吗?你知道箭头函数只包含一个没有正文的语句会隐式返回该语句的结果吗?
  • ^ () =&gt; fn()() =&gt; { return fn(); } 相同,参见arrow function documentation
  • @3limin4t0r:感谢您的链接!现在我明白了
【解决方案2】:

这是在官方文档here 中写的。

useEffect 返回的任何函数都用于“清理”。

在您的第一个示例中,doRequest 返回 undefined 以外的其他内容,React 将在组件卸载时尝试将其作为函数调用以“清理”。

useEffect 带有清理功能的示例:

useEffect(() => {
  document.addEventListener("resize", handleResize);
  // This is a "clean up" function
  return () => {
    document.removeEventListener("resize", handleResize);
  };
}, []);

没有清理功能的useEffect 示例。请注意,这很糟糕,因为在组件卸载后侦听器仍会触发。

useEffect(() => {
  document.addEventListener("resize", handleResize);
}, []);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-26
    • 2022-01-09
    • 2021-02-11
    • 1970-01-01
    相关资源
    最近更新 更多