前言随着react16.8的发布,hooks的新特性也随之而来。hooks的到来让函数组件焕发了强大的能力,足以替代之前的类组件。功能组件依赖于useState和useEffect等钩子来维护变量状态和提取副作用。原生的useEffect虽然功能强大,但是那些常用的写法每次都得手动复现,不仅影响开发效率,而且容易出错。接下来给大家推荐一个npm第三方库,里面会封装useEffect相关的常用写法,绝对可以帮助到你的开发,让你的开发如鱼得水。这个库的名字叫pluto-hooks,它的相关资料也可以在npm官网搜索到。以下是npm地址https://www.npmjs.com/package...本项目中的大部分hook都与useEffect有关。当然,还有其他的。开发人员可以选择使用它们。下面介绍一下这个库的使用方法。安装首先需要在react项目中安装。推荐使用yarn安装yarnyarnaddpluto-hooksnpmnpmipluto-hooks。您可以从“pluto-hooks”导入{useEffectOnece};useEffectOnece(()=>{console.log("触发器");});前置知识要理解下面的用法,你得对react组件(这里只用Functional组件)和hooks有一定的了解,当组件状态改变时会触发渲染组件,useState改变状态,子组件调用父组件的方法来改变父组件的状态。props改变父组件,重新渲染生成该组件的工厂函数重新执行(比如工厂函数放在useCallback中,依赖值改变)。useEffect的两个参数effect接收一个函数,返回一个销毁函数(指return返回的清理函数),如果useEffect是第一个参数传入async,返回值变成Promise,会引起react调用destroy函数报错:function.applyisundefineddeps改变参数接收一个数组,里面存放的是useEffect的依赖值,在页面重新渲染时reactwill对比之前的deps和新的deps,这里是浅比较,比较deps中的每个元素,所以当deps=[{}]时,每次都会执行effect,因为{}!==={}hooks引入useCountUpdateEffect执行第n次渲染和deps变化。有时我们在项目开发中需要在组件渲染到一定次数后触发一个方法。比如使用input输入文字时,每次按下键盘都会触发render。我们可以使用useCountUpdateEffect来控制效果的触发时间注意:第一次渲染也算一个例子importReact,{useState}来自“react”;从“../index”导入useCountUpdateEffect;导出默认值()=>{const[text,setText]=useState('');functioninputChange(e){setText(e.target.value)}useCountUpdateEffect(()=>{console.log('useCountUpdateEffectexecution');},10);return(
);};useRangeUpdateEffect在componentrenderingtimes[range[0],range[1]],它是useCountUpdateEffect的升级版,有时候我们并不一定要在一定的渲染次数触发回调函数,而是一定要在a内连续触发一定范围。第二个参数传入一个数组range,range[0]为左边界,range[1]为右边界。如果传入If[,right],则默认为[0,right]。如果传入[left,],大于left(含left)的渲染次数会触发效果。如果传入[],则与useEffect没有区别。三个参数依赖depsexampleimportReact,{useState}from"react";importuseRangeUpdateEffectfrom"../index";exportdefault()=>{const[text,setText]=useState('');函数在inputChange(e){setText(e.target.value)}useRangeUpdateEffect(()=>{console.log('useRangeUpdateEffect');},[5,10]);返回(
);};同样,这里也会统计初始渲染,如果想忽略第一次渲染,可以调整第二个参数的范围useCompareEffecttype{)=>boolean}我们在前面的知识中提到过,useEffect默认只会对deps进行浅比较,但是使用useCompareEffect我们可以自定义deps的比较。第三个参数是比较函数。depsEqual的第一个参数是旧的deps数组,第二个参数是新的deps数组。这个函数返回一个boolean值,当为true时,effect不会执行,否则会执行exampleimportReact,{useState}from"react";importuseCompareEffectfrom"../index"){const[count1,setCount1]=useState(0)const[count2,setCount2]=useState(0)const[count,setCount]=useState(0)constcompareFn=(old,next)=>{console.log('old,next:',old,next);returnold[1]===next[1]}useCompareEffect(()=>{//只有当count2改变时,才会触发setCount(state=>state+1)},[count1,count2],compareFn)return(
{count}
{count1}
{count2}
{setCount1(state=>state+1)}}>count1{setCount2(state=>state+1)}}>count2)}useDeepCompareEffect这个钩子是基于上面使用CompareEffect。UseDeepCompareEffect在组件重新渲染时执行。这个hook会对deps进行深度比较,如果相等则执行effecttype{effect:EffectCallback,deps:DependencyList,}useAsyncEffect看过前置知识的朋友可能还记得useEffect的第一个参数不能传给异步功能。如果你真的想使用异步功能,你可以调用useAsyncEffect示例importReact,{useState}from"react";importuseAsyncEffectfrom"../index"exportdefault()=>{constfn=()=&g吨;{returnnewPromise(resolve=>{setTimeout(()=>{resolve()},3000)})}useAsyncEffect(async()=>{console.log('wait...');awaitfn()console.log('完成');},[]);};上面的代码会在组件初始化时显示“Wait...”,3秒后显示“Complete”。useDebounceFn处理去抖功能const{run,cancel,flush}=useDebounceFn(fn:(...args:any[])=>any,options?:Options);run,cancel,flush是一个可执行函数run:开始执行带防抖的fn,传入run的参数会传递给fncancel:取消fnflush的执行:立即执行fn,不会等到wait结束useDebounceEffecttype{effect:EffectCallback,deps?:DependencyList,options:DebounceOptions}会带上带防抖的传入Effect,options可以配置防抖Jitter参数options参数(默认值):[options.wait=1000](number):等待时间,以毫秒为单位[options.leading=false](boolean):指定在延迟开始之前调用。[options.maxWait](number):设置func允许延迟的最大值。[options.trailing=true](boolean):指定在尾部结束后调用。useThrottleFnhookconst{run,cancel,flush}=useThrottleFn(fn:(...args:any[])=>any,options?:Options);options参数:[options.wait=1000](number):等待时间,以毫秒为单位。[options.leading=true](boolean):指定在节流开始前调用。[options.trailing=true](boolean):指定在节流结束后调用。run、cancel、flush是可执行函数run:开始执行带防抖的fn,传给run的参数会传递给fncancel:取消执行fnflush:不等到等待时间结束立即执行fnuseThrottleEffect将传入的Effect带入Stream函数,options可以配置throttling参数类型{effect:EffectCallback,deps:DependencyList,options:ThrottleOptions}optionsparameter:[options.wait=1000](number):等待时间,单位毫秒。[options.leading=true](boolean):指定在节流开始前调用。[options.trailing=true](boolean):指定在节流结束后调用。useEffectOnce只执行type{effect:EffectCallback,}useFirstMountState判断组件是否第一次渲染,返回一个布尔示例importReact,{useEffect,useState}from"react";importuseFirstMountStatefrom"../index"exportdefault()=>{const[count,setCount]=useState(0);constisfirst=useFirstMountState()console.log('isfirst:',isfirst);返回(
first:{isfirst}
setCount((c)=>c+1)}>重新渲染
)}可以看到后面点击reRender时,useFirstMountState()在第一次没有执行useUpdateEffect时返回false。项目github地址为https://github.com/plutoLam/h...,使用bruce-app构建,打包打包