先要晓得几点前提要点

  1. 在functional component中,每一次props的变动、执行setState操作都会导致组件办法从新执行。
  2. 基于1,组件办法执行后,所有的间接定义的const、let变量都会从新定义。
  3. 所以对于不须要变动的常量,个别用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函数