useEffect支持async及await使用方式.docx

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)

1亿VIP精品文档

相关文档