当前位置: 首页 > Web前端 > JavaScript

ReactHooks精髓探秘——useRef源码详解

时间:2023-03-27 01:17:41 JavaScript

首先,你需要知道几个前提条件。在函数式组件中,每次props的改变和setState操作的执行都会导致组件方法重新执行。基于1,组件方法执行后,所有直接定义的const和let变量都会被重新定义。所以,对于不需要改变的常量,一般用useRef封装。常用使用方法:consta=useRef(initalValue);a不会在执行组件方法时被重新赋值。那么useRef在这里基本上做了什么?useRef本质上是ReactCurrentDispatcher.current上的一种方法,它接收一个初始值并返回一个对象,该对象只有一个当前属性。当执行组件方法时,不会重置当前值,即每次执行组件方法时使用相同的值。当然,这里有个问题,返回的对象为什么不重置呢?应该是react采用了时间序列保存的方式。初始化时,将值记录在一个对象中;组件方法重复执行时,从这个对象中取出,赋值给a。我们看下面的源码片段,就是初始化ref的源码:useRef:function(initialValue){currentHookNameInDev='useRef';mountHookTypesDev();returnmountRef(initialValue);},functionmountRef(initialValue){varhook=mountWorkInProgressHook();varref={current:initialValue};{对象.密封(参考);}hook.memoizedState=ref;returnref;}注意:Object.seal只是让ref中的key不能被删除,但是value是可以改变的。下面是更新ref的代码片段(第二次后执行组件方法):useRef:function(initialValue){currentHookNameInDev='useRef';updateHookTypesDev();返回更新参考();//可以注意到这是update},这里mountHookTypesDev和updateHookTypesDev并不重要。主要逻辑是mountRef和updateRef方法。可以看出updateRef实际上返回的是hook中记录的memoizedState。至于mountWorkInProgressHook和updateWorkInProgressHook,是两个比较复杂的方法。说到hook的本质,其实useState也是这样存值的。详见另一篇文章:Reacthooks源码核心:workInProgressHook函数