Sylvenas / Blog

blog
https://sylvenas.github.io
Creative Commons Attribution 4.0 International
2 stars 0 forks source link

[Note] React Fiber 数据结构 #1

Open Sylvenas opened 3 years ago

Sylvenas commented 3 years ago
interface Fiber {
  /**
   * ⚛️ 节点的类型信息
   */
  // 标记 Fiber 类型, 例如函数组件、类组件、宿主组件
  tag: WorkTag,
  // 节点元素类型, 是具体的类组件、函数组件、宿主组件(字符串)
  type: any,

  /**
   * ⚛️ 结构信息
   */ 
  return: Fiber | null,
  child: Fiber | null,
  sibling: Fiber | null,
  // 子节点的唯一键, 即我们渲染列表传入的key属性
  key: null | string,

  /**
   * ⚛️ 节点的状态
   */
  // 节点实例(状态):
  //    对于宿主组件,这里保存宿主组件的实例, 例如DOM节点。
  //    对于类组件来说,这里保存类组件的实例
  //    对于函数组件说,这里为空,因为函数组件没有实例
  stateNode: any,
  // 新的、待处理的props
  pendingProps: any,
  // 上一次渲染的props
  memoizedProps: any, // The props used to create the output.
  // 上一次渲染的组件状态
  memoizedState: any,

  /**
   * ⚛️ 副作用
   */
  // 当前节点的副作用类型,例如节点更新、删除、移动
  // 详情参考源码: https://github.com/ddzy/react/blob/master/packages/shared/ReactSideEffectTags.js
  effectTag: SideEffectTag,
  // 和节点关系一样,React 同样使用链表来将所有有副作用的Fiber连接起来
  nextEffect: Fiber | null,

  /**
   * ⚛️ 替身
   * 指向旧树中的节点
   */
  alternate: Fiber | null,
}
Sylvenas commented 3 years ago

其中, tag 属性及其重要, React 在源码中也标注的很明确. 在后续的大循环进行更新每个节点(beginWork)时, React 根据 fiber.tag 来对不同的组件进行更新

// 函数组件
export const FunctionComponent = 0;
// 类组件
export const ClassComponent = 1;
// RootFiber
export const HostRoot = 3;
// 诸如`div`、`p`等原生DOM节点
export const HostComponent = 5;
// React.Fragment, 不会渲染出真实DOM节点
export const Fragment = 7;
export const Mode = 8;
export const ContextConsumer = 9;
export const ContextProvider = 10;
export const ForwardRef = 11;
export const Profiler = 12;
// 与LazyComponent配合使用, 异步组件
export const SuspenseComponent = 13;
export const MemoComponent = 14;
export const SimpleMemoComponent = 15;
// 与SuspenseComponent配合使用, 异步组件
export const LazyComponent = 16;
export const IncompleteClassComponent = 17;
export const DehydratedSuspenseComponent = 18;
export const EventComponent = 19;
export const EventTarget = 20;