编程语言
首页 > 编程语言> > react源码解析13.hooks源码

react源码解析13.hooks源码

作者:互联网

react源码解析13.hooks源码

视频讲解(高效学习):进入学习

往期文章:

1.开篇介绍和面试题

2.react的设计理念

3.react源码架构

4.源码目录结构和调试

5.jsx&核心api

6.legacy和concurrent模式入口函数

7.Fiber架构

8.render阶段

9.diff算法

10.commit阶段

11.生命周期

12.状态更新流程

13.hooks源码

14.手写hooks

15.scheduler&Lane

16.concurrent模式

17.context

18事件系统

19.手写迷你版react

20.总结&第一章的面试题解答

hook调用入口

​ 在hook源码中hook存在于Dispatcher中,Dispatcher就是一个对象,不同hook 调用的函数不一样,全局变量ReactCurrentDispatcher.current会根据是mount还是update赋值为HooksDispatcherOnMount或HooksDispatcherOnUpdate

ReactCurrentDispatcher.current = 
  current === null || current.memoizedState === null//mount or update
  ? HooksDispatcherOnMount
	: HooksDispatcherOnUpdate;  
const HooksDispatcherOnMount: Dispatcher = {//mount时
  useCallback: mountCallback,
  useContext: readContext,
  useEffect: mountEffect,
  useImperativeHandle: mountImperativeHandle,
  useLayoutEffect: mountLayoutEffect,
  useMemo: mountMemo,
  useReducer: mountReducer,
  useRef: mountRef,
  useState: mountState,
  //...
};

const HooksDispatcherOnUpdate: Dispatcher = {//update时
  useCallback: updateCallback,
  useContext: readContext,
  useEffect: updateEffect,
  useImperativeHandle: updateImperativeHandle,
  useLayoutEffect: updateLayoutEffect,
  useMemo: updateMemo,
  useReducer: updateReducer,
  useRef: updateRef,
  useState: updateState,
  //...
};

hook数据结构

​ 在FunctionComponent中,多个hook会形成hook链表,保存在Fiber的memoizedState的上,而需要更新的Update保存在hook.queue.pending中

const hook: Hook = {
  memoizedState: null,//对于不同hook,有不同的值
  baseState: null,//初始state
  baseQueue: null,//初始queue队列
  queue: null,//需要更新的update
  next: null,//下一个hook
};

下面来看下memoizedState对应的值

useState&useReducer

之所以把useState和useReducer放在一起,是因为在源码中useState就是有默认reducer参数的useReducer。

useEffect

useRef

​ sring类型的ref已经不在推荐使用(源码中string会生成refs,发生在coerceRef函数中),ForwardRef只是把ref通过传参传下去,createRef也是{current: any这种结构,所以我们只讨论function或者{current: any}的useRef

//createRef返回{current: any}
export function createRef(): RefObject {
  const refObject = {
    current: null,
  };
  return refObject;
}

useMemo&useCallback

useLayoutEffect

useLayoutEffect和useEffect一样,只是调用的时机不同,它是在commit阶段的commitLayout函数中同步执行

forwardRef

forwardRef也非常简单,就是传递ref属性

export function forwardRef<Props, ElementType: React$ElementType>(
  render: (props: Props, ref: React$Ref<ElementType>) => React$Node,
) {
  
  const elementType = {
    $$typeof: REACT_FORWARD_REF_TYPE,
    render,
  };
  
  return elementType;
}
//ForwardRef第二个参数是ref对象
let children = Component(props, secondArg);

标签:function,const,hooks,memoizedState,react,hook,源码,null,ref
来源: https://www.cnblogs.com/ityk1024/p/15640964.html