将 Async 函数放入 useEffect 后出现错误

Getting error after I put Async function in useEffect

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

react-dom.development.js:21857 Uncaught TypeError: destroy is not a function

Consider adding an error boundary to your tree to customize error handling behavior.

  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;

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

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

useEffect 清理函数

如果您 return 来自 useEffect 钩子函数的任何东西,它必须是一个 清理函数 。当组件卸载时,此函数将 运行。这可以被认为大致等同于 class 组件中的 componentWillUnmount 生命周期方法。

useEffect(() => { 
  doSomething();

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

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

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

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

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

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

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

useEffect 挂钩的一个功能是清理功能。如果你 return 来自 useEffect 钩子函数的任何东西,它一定是一个清理函数。当组件卸载时,此函数将 运行。这可以被认为大致等同于 class components.

中的 componentWillUnmount 生命周期方法。

在JavaScript中,标有async关键字的函数允许使用await特性,它允许开发者在等待异步任务执行时暂停函数的执行结束。异步函数也总是 return 一个 Promise;如果该函数还没有 return,return 值会自动包装在 Promise 中。

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

现在,这些花絮是如何聚集在一起导致如此神秘的错误的?简单的说,getResponse的值,也就是一个Promise,在useEffect hook中变成了箭头函数的return的值。还记得 useEffect 钩子期望清理函数被 returned 吗? Promise 不是函数。所以 React 会出错并产生错误。

要修复您的应用,请更改 useEffect 箭头函数以添加大括号并删除隐式 Return,如图所示:

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

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

我像这样使用了 IIFE,而且成功了!!-

之前是这样的-

useEffect(async ()=>{
    const awesome_value = await AsyncStorage.getItem('awesome')
    setAwesome(awesome_value)
},[]);

现在我改成了这个-

useEffect( ()=>{
   (async() => {const awesome_value = await AsyncStorage.getItem('awesome')
   setAwesome(awesome_value)} ) ();
},[]);