先要晓得几点前提要点
- 在functional component中,每一次props的变动、执行setState操作都会导致组件办法从新执行。
- 基于1,组件办法执行后,所有的间接定义的const、let变量都会从新定义。
- 所以对于不须要变动的常量,个别用useRef封装起来。
常见的应用办法:
const a = useRef(initalValue);
在执行组件办法的时候,a不会被从新赋值。那么useRef在这里实质上干了什么呢?
useRef实质上是ReactCurrentDispatcher.current上的一个办法,这个办法接管一个初始值,返回一个对象,这个对象中只有一个current属性。
在执行组件办法的时候,这个current的值不会被重置,也就是说,每一次执行组件办法,用到的都是同一个值。
当然这里有一个问题,返回的这个对象为什么不会被重置?
应该是react用了一种时序的保留办法,在初始化时,将值记录在一个对象中;反复执行组件办法的时候,再从这个对象中取出来赋值到了a上。
上面看源码片段,这是初始化ref的源码:
useRef: function (initialValue) { currentHookNameInDev = 'useRef'; mountHookTypesDev(); return mountRef(initialValue);},
function mountRef(initialValue) { var hook = mountWorkInProgressHook(); var ref = { current: initialValue }; { Object.seal(ref); } hook.memoizedState = ref; return ref;}
附:Object.seal只是让ref里的key无奈删除,value能够扭转。
上面是更新ref(第二次当前执行组件办法)的代码片段:
useRef: function (initialValue) { currentHookNameInDev = 'useRef'; updateHookTypesDev(); return updateRef(); // 能够留神到这里是update},
这里mountHookTypesDev和updateHookTypesDev不重要。次要逻辑是mountRef和updateRef办法。
能够看到,updateRef其实就是返回了hook里记录的memoizedState
至于mountWorkInProgressHook和updateWorkInProgressHook,是两个比较复杂的办法。波及到hook的实质,实际上useState也是用这个形式存储值的。
详见另一篇文章:react hooks源码外围:workInProgressHook函数