【问题标题】:Getting error after I put Async function in useEffect将异步函数放入 useEffect 后出现错误
【发布时间】:2020-02-18 01:42:02
【问题描述】:

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

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

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

  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;

【问题讨论】:

    标签: reactjs fetch use-effect


    【解决方案1】:

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

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

    useEffect 清理函数

    如果您从useEffect 挂钩函数返回任何内容,则它必须是清理函数。此函数将在组件卸载时运行。这可以认为大致相当于类组件中的componentWillUnmount生命周期方法。

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

    【讨论】:

    • 非常感谢。有效。所以,本质上,它周围的两个括号 {} 有区别吗?你能给我关键字或短语,我可以用谷歌搜索并阅读更多相关信息吗?
    • @IrakliTchigladze 是的,箭头函数的“隐式返回”。还要查看 useEffect 的工作原理以及从中返回的内容。很高兴它成功了!
    【解决方案2】:

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

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

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

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

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

    【讨论】:

    • 值得注意的是,虽然这个解决方案确实有效,但 IIFE 与它无关,它周围的大括号抑制了隐式返回值,这就是它起作用的原因。
    【解决方案3】:

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

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

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

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

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

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

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

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

    【讨论】:

      【解决方案4】:

      我就这样用过 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)} ) ();
      },[]);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-07-07
        • 2021-01-24
        • 2018-02-10
        • 2021-03-15
        • 2019-01-15
        • 2021-01-16
        相关资源
        最近更新 更多