reactjs 将异步函数置于useEffect后出现错误

dzjeubhm  于 2022-12-18  发布在  React
关注(0)|答案(5)|浏览(151)

在useEffect函数中,如果我只提到getResults函数变量,应用不会崩溃,但当我像下面的代码那样调用它时,我会得到以下错误:
js:21857未捕获的类型错误: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;
bwleehnv

bwleehnv1#

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

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

useEffect清理函数

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

useEffect(() => { 
  doSomething();

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

pepwfjgg2#

异步函数实际上只是promise的语法糖,所以当你调用一个异步函数时,它会返回一个promise。
相反,您可以使用IIFE(立即调用函数表达式) Package 异步函数,如下所示,这样就不会向useEffect返回任何内容,也不会将其用作清理函数:

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

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

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

6bc51xsx3#

我像这样使用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)} ) ();
},[]);
hgc7kmma

hgc7kmma4#

上面的简单代码导致应用崩溃的原因是useEffect钩子、async函数和速记箭头函数语法的工作方式。
useEffect钩子的一个特性是一个清理函数。如果你从useEffect钩子函数返回任何东西,它必须是一个清理函数。这个函数将在组件卸载时运行。这可以被认为大致等同于类组件中的componentWillUnmount生命周期方法。
在JavaScript中,使用async关键字标记的函数允许使用await功能,该功能允许开发人员在等待异步任务完成时暂停函数的执行。如果函数还没有返回一个,那么返回值将自动 Package 在Promise中。
最后,速记箭头函数语法允许开发人员省略函数体周围的花括号,这对于简单的一行程序很有用。函数体的值自动成为箭头函数的返回值,不再需要return关键字。此功能称为隐式返回。
那么,这些小细节是如何组合在一起导致这样一个神秘的错误的呢?简单地说,getResponse的值,即Promise,成为useEffect钩子中arrow函数的返回值。请记住,useEffect钩子期望返回一个清理函数。Promise不是函数。因此React出错并产生错误。
要修复您的应用,请更改useEffect箭头函数以添加大括号并移除隐式返回,如下所示:

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

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

7gcisfzg

7gcisfzg5#

愚蠢的,但是我已经从我的useEffect返回了一个响应,我发现了这个错误。请检查你是否也从你的效果返回了一些东西。

相关问题