将异步函数放入 useEffect 后出现错误

IT技术 reactjs fetch use-effect
2021-05-22 02:43:11

在 useEffect 函数中,如果我只提到 getResults 函数变量,应用程序不会崩溃。但是当我在下面的代码中调用它时,我收到这些错误:

react-dom.development.js:21857 Uncaught TypeError: destroy 不是函数

考虑向树添加错误边界以自​​定义错误处理行为。

  function App() {
  const [foods, setFoods] = useState([]);
  const [isLoaded, setIsLoaded] = useState(false);
  useEffect(() => getResponse());
  const getResponse = async () => {
    const response = await fetch(sampleRequest);
    const data = await response.json();
    setFoods(data.hits);
  };
  let query = "Tomato";
  let sampleRequest = `https://api.edamam.com/search?q=${query}&app_id=${"1811484f"}&app_key=${"9cac93361efc99e2ebfbb8a453882af8"}`;

  return (
    <div className="App">
      <div className="main">
        <div className="navbars">
          {" "}
          <Navbars></Navbars>
        </div>
        <div className="listings">
          <Listing></Listing>
          <Listing></Listing>
          <Listing></Listing>
          <Listing></Listing>
          <Listing></Listing>
          <Listing></Listing>
          <Listing></Listing>
          <Listing></Listing>
          <Listing></Listing>
          <Listing></Listing>
        </div>
        <div className="footer">
          <h5>Made By YoYo Strangler in 2019</h5>
        </div>
      </div>
    </div>
  );
}

export default App;
3个回答

您正在返回getResponse()useEffect函数调用的结果如果你从 返回任何东西useEffect,它必须是一个函数。将您的代码更改为此应该可以修复它,因为您不再从该useEffect函数返回任何内容

useEffect(() => { 
  getResponse();
});

useEffect清理功能

如果你从useEffect钩子函数返回任何东西,它必须是一个清理函数此函数将在组件卸载时运行。这可以被认为大致相当于componentWillUnmount类组件中生命周期方法。

useEffect(() => { 
  doSomething();

  return () => {
    console.log("This will be logged on unmount");
  }
});

异步函数实际上只是Promise的语法糖,因此当您调用异步函数时,它会返回一个Promise。

相反,您可以像这样使用 IIFE(立即调用的函数表达式)包装异步函数,因此不会返回任何内容并将其useEffect用作清理函数:

useEffect(() => { 
  (async () => getResponse())();
});

编辑:或正如@json 在下面的评论中指出的那样。只是:

useEffect(() => { getResponse() });

上面的简单代码导致您的应用程序崩溃的原因是useEffect钩子、async函数和速记箭头函数语法的工作方式。

useEffect 钩子的一个特性是一个清理函数。如果你从 useEffect 钩子函数返回任何东西,它必须是一个清理函数。此函数将在组件卸载时运行。这可以被认为大致相当于类组件中的 componentWillUnmount 生命周期方法。

在 JavaScript 中,标有async关键字的函数可以使用该await功能,这让开发人员可以在等待异步任务完成时暂停函数的执行。异步函数也总是返回一个 Promise;如果函数还没有返回一个,返回值会自动包装在一个 Promise 中。

最后,简写箭头函数语法允许开发人员省略函数体周围的花括号,这对于简单的单行代码很有用。函数体的值自动成为箭头函数的返回值,不需要return关键字。此功能称为隐式返回。

现在,这些花絮是如何结合在一起导致如此神秘的错误的?简单来说,getResponse就是一个Promise的值,变成了useEffect钩子中箭头函数的返回值。还记得 useEffect 钩子期望返回一个清理函数吗?Promise 不是函数。所以 React 绊倒并产生错误。

要修复您的应用程序,请更改 useEffect 箭头函数以添加花括号并删除隐式返回,如下所示:

useEffect(() => { 
  getResponse();
});

现在, useEffect 钩子中的箭头函数返回undefined,这是可以接受的,并告诉 React 不需要清理函数。这将解决问题,但是如果 React 在发生这种情况时给出更有用的错误消息,那就太好了!