第
useEffect支持async及await使用方式
目录引言背景React为什么要这么做?useEffect怎么支持async...await...自定义hooks还可以支持useEffect的清除机制么?总结与思考
引言
本文是深入浅出ahooks源码系列文章的第六篇,这个系列的目标主要有以下几点:
加深对Reacthooks的理解。学习如何抽象自定义hooks。构建属于自己的Reacthooks工具库。培养阅读学习源码的习惯,工具库是一个对源码阅读不错的选择。
注:本系列对ahooks的源码解析是基于v3.3.13。自己folk了一份源码,主要是对源码做了一些解读,可见详情。
背景
大家在使用useEffect的时候,假如回调函数中使用async...await...的时候,会报错如下。
看报错,我们知道effectfunction应该返回一个销毁函数(effect:是指return返回的cleanup函数),如果useEffect第一个参数传入async,返回值则变成了Promise,会导致react在调用销毁函数的时候报错。
React为什么要这么做?
useEffect作为Hooks中一个很重要的Hooks,可以让你在函数组件中执行副作用操作。它能够完成之前ClassComponent中的生命周期的职责。它返回的函数的执行时机如下:
首次渲染不会进行清理,会在下一次渲染,清除上一次的副作用。卸载阶段也会执行清除操作。
不管是哪个,我们都不希望这个返回值是异步的,这样我们无法预知代码的执行情况,很容易出现难以定位的Bug。所以React就直接限制了不能useEffect回调函数中不能支持async...await...
useEffect怎么支持async...await...
竟然useEffect的回调函数不能使用async...await,那我直接在它内部使用。
做法一:创建一个异步函数(async...await的方式),然后执行该函数。
useEffect(()={
constasyncFun=async()={
setPass(awaitmockCheck());
asyncFun();
},[]);
做法二:也可以使用IIFE,如下所示:
useEffect(()={
(async()={
setPass(awaitmockCheck());
})();
},[]);
自定义hooks
既然知道了怎么解决,我们完全可以将其封装成一个hook,让使用更加的优雅。我们来看下ahooks的useAsyncEffect,它支持所有的异步写法,包括generatorfunction。
思路跟上面一样,入参跟useEffect一样,一个回调函数(不过这个回调函数支持异步),另外一个依赖项deps。内部还是useEffect,将异步的逻辑放入到它的回调函数里面。
functionuseAsyncEffect(
effect:()=AsyncGeneratorvoid,void,void|Promisevoid,
//依赖项
deps:DependencyList,
//判断是AsyncGenerator
functionisAsyncGenerator(
val:AsyncGeneratorvoid,void,void|Promisevoid,
):valisAsyncGeneratorvoid,void,void{
//Symbol.asyncIterator:/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Symbol/asyncIterator
//Symbol.asyncIterator符号指定了一个对象的默认异步迭代器。如果一个对象设置了这个属性,它就是异步可迭代对象,可用于forawait...of循环。
returnisFunction(val[Symbol.asyncIterator]);
useEffect(()={
conste=effect();
//这个标识可以通过yield语句可以增加一些检查点
//如果发现当前effe
原创力文档

文档评论(0)