将异步函数放入 useEffect 后出现错误
Posted
技术标签:
【中文标题】将异步函数放入 useEffect 后出现错误【英文标题】:Getting error after I put Async function in 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;
【问题讨论】:
【参考方案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 不需要清理函数。这将解决问题,但如果 React 在发生这种情况时给出更有用的错误消息,那就太好了!
【讨论】:
【参考方案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) ) ();
,[]);
【讨论】:
以上是关于将异步函数放入 useEffect 后出现错误的主要内容,如果未能解决你的问题,请参考以下文章
Next.js 500 内部服务器错误在 404 页面内调用 useEffect Hook 后立即出现
如何在 React 的 UseEffect() 中调用异步函数?
如何取消 useEffect 清理函数中的所有订阅和异步任务?