React链表结构的核心概念

React链表结构的核心概念

1. Fiber

  • 结构上,是一个对象
  • 描述了一个React元素或Dom节点
  • 新的协调引擎,主要目的是使Virtual DOM可以进行增量式渲染
ts 复制代码
export type Fiber = {
    // 标记组件类型,如函数组件、类组件、原生便签等
    tag: WorkTag,
    
    // 标记节点的唯一性,diff时候判断节点是否能复用的依据之一,其他两个是同一层级、类型相同
    key: null | string,
    
    // 保存节点在协调阶段的element.type的值
    elementType: any,
    
    // fiber的type
    type: any,
    
    // 不同类型的组件,stateNode代表的值不同:
    // 原生标签,stateNode是dom节点
    // 类组件,stateNode是实例
    stateNode: any,
    
    // 父fiber
    return: Fiber | null,
    
    // fiber children是单链表结构,这也是React VDOM DIFF算法中单向查找的原因(Vue VDOM DIFF中是双向查找)
    // 第一个子fiber
    child: Fiber | null,
    // 下一个兄弟fiber
    sibling: Fiber | null,
    // 标记此fiber在当前层级下的位置下标
    index: number,
    
    // 节点的ref
    ref: null 
        | (((handle: mixed) => void) & {_stringRef: ?sting, ...}}
        | RefObject,
    
    // 还未更新完成组件的props
    pendingProps: any,
    // 上次组件更新的props
    memoizedProps: any,
    
    // update的queue, update里包括了状态值、callback等
    // update是个单向循环链表
    updateQueue: mixed,
    
    // 类组件中存的是状态值
    // 函数组件中存的是第0个hook, hooks也是单链表
    memoizedState: any,
    
    // 如果该组件消费了context value, 这里存的就是context对象
    dependencies: Dependencies | null
    
    // 如concurrent模式
    mode: TypeOfMode,
    
    // 标记fiber的effect, 如Placement(末尾插入appendChild、向前插入insertBefore)、Update(更新)等
    flags: Flags,
    // 子树的flags
    subtreeFlags: Flags,
    // 如果有要删除的子fiber, 则存在这个数组中
    deletions: Array<Fiber> | null
    
    // 标记节点的lanes
    lanes: Lanes,
    childLanes: Lanes,
    
    // 上一个fiber
    alternate: Fiber | null
}

2. Hook

  • 解决类组件难以解决的问题,比如状态复用、组件臃肿等
  • 每次函数组件执行的时候,hook都会再次执行;Vue Composition只是首次执行一次
  • 结构上,为单链表,hook顺序代表链表的唯一性,所以引用hook不能使用条件、循环等语句
ts 复制代码
export type Hook = {
    // 如果是useState或者useReducer, 这个memoizedState记录的是状态值
    // 如果是useEffect或useLayoutEffect,  这个memoizedState记录的是effect
    // 如果是useMemo,  这个memoizedState记录的是新值和依赖数组,即[nextValue, nextDeps]
    // 如果是useDeferredValue,  这个memoizedState记录的是这个value
    memoizedState: any,
    baseState: any,
    baseQueue: Update<any, any> | null,
    queue: any,
    // 下一个hook, 单链表结构
    next: Hook | null
}

3. Update

  • 初次渲染、setState、forceUpdate的更新
  • 通过批量更新实现的异步更新
ts 复制代码
function enqueueUpdate<S, A>(
    fiber: Fiber,
    queue: UpdateQueue<S, A>,
    update: Update<S, A>,
    lane: Lane
) {
    ...
}

4. Effect

  • useEffect和useLayoutEffect处理effect

函数组件初次渲染

  • 记录effect和deps
  • pushEffect函数,把effect单向循环链表,存储在fiber.updateQueue.lastEffect上
ts 复制代码
// effect
function mountEffect(
    create: () => (() => void) | void,
    deps: Array<mixed> | void | null
):void {
    return mountEffectImpl(
        PassiveEffect | PassiveStaticEffect,
        HookPassive,
        create,
        deps
    )
}

function mountEffectImpl(fiberFlags, hookFlags, create, deps): void {
    const hook = mountWorkInProgressHook();
    const nextDeps = deps === undefined ? null : deps;
    currentlyRenderingFiber.flags = fiberFlags;
    hook.memoizedState = pushEffect(
        HookHasEffect | hookFlags,
        create,
        undefined,
        nextDeps
    )
}

函数组件更新阶段

  • 相对于初次渲染阶段,更新阶段的不同之处在于多了对deps的对比,如果组件更新前后,依赖项不变,则后续的effect并不会添加到updateQueue中,也就意味着create函数不会执行。
  • 并且,初次渲染阶段不会记录destory函数,只需函数组件更新阶段记录到effect中。
  • 在记录阶段,effect都是记录到fiber.updateQueue中

5. 总结

  • 单向链表fiber、hook
  • 单向循环链表update、effect
相关推荐
lbb 小魔仙2 小时前
【HarmonyOS实战】React Native 表单实战:自定义 useReactHookForm 高性能验证
javascript·react native·react.js
早點睡3906 小时前
高级进阶 ReactNative for Harmony 项目鸿蒙化三方库集成实战:react-native-drag-sort
react native·react.js·harmonyos
C澒7 小时前
Vue 项目渐进式迁移 React:组件库接入与跨框架协同技术方案
前端·vue.js·react.js·架构·系统架构
发现一只大呆瓜8 小时前
虚拟列表:从定高到动态高度的 Vue 3 & React 满分实现
前端·vue.js·react.js
全栈探索者9 小时前
列表渲染不用 map,用 ForEach!—— React 开发者的鸿蒙入门指南(第 4 期)
react.js·harmonyos·arkts·foreach·列表渲染
程序员Agions10 小时前
useMemo、useCallback、React.memo,可能真的要删了
前端·react.js
NEXT0610 小时前
React Hooks 进阶:useState与useEffect的深度理解
前端·javascript·react.js
早點睡39011 小时前
基础入门 React Native 鸿蒙跨平台开发:react-native-flash-message 消息提示三方库适配
react native·react.js·harmonyos
早點睡39012 小时前
高级进阶 ReactNative for Harmony项目鸿蒙化三方库集成实战:react-native-image-picker(打开手机相册)
react native·react.js·harmonyos
早點睡39012 小时前
基础入门 React Native 鸿蒙跨平台开发:react-native-easy-toast三方库适配
react native·react.js·harmonyos