Jinuss's blog Jinuss's blog
首页
  • 源码合集

    • Leaflet源码分析
    • Openlayers源码合集
    • vue3源码
  • HTML
  • CSS
  • 技术文档
  • GitHub技巧
  • 学习
  • 实用技巧
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

东流

Web、WebGIS技术博客
首页
  • 源码合集

    • Leaflet源码分析
    • Openlayers源码合集
    • vue3源码
  • HTML
  • CSS
  • 技术文档
  • GitHub技巧
  • 学习
  • 实用技巧
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 《React源码》笔记
  • React-reconciler
东流
2026-02-06
目录

beginWork方法解析

# 概览

beginWork方法是React中非常重要的一个方法,它负责处理Fiber节点的beginWork阶段。在beginWork阶段,React会根据Fiber节点的tag来调用不同的方法,来处理不同类型的Fiber节点。

# 源码分析

# beginWork

beginWork方法的源码如下:

function beginWork(current, workInProgress, renderLanes) {
  if (current != null) {
   // 有旧Fiber,说明是更新操作,对比是否需要更新
    // 对比新旧props
    if (current.memoizedProps !== workInProgress.pendingProps) {
      didReceiveUpdate = true;// 表示需要更新
    } else {
      // 若Props不同,则检查是否有计划的更新或context变化
      const hasScheduledUpdateOrContext = checkScheduledUpdateOrContext(
        current,
        renderLanes,
      );
      if (
        !hasScheduledUpdateOrContext &&
        (workInProgress.flags & DidCapture) === NoFlags
      ) {
        // 没有更新且没有捕获错误,尝试提前退出
        didReceiveUpdate = false;
        return attemptEarlyBailoutIfNoScheduledUpdate(
          current,
          workInProgress,
          renderLanes,
        );
      }
      
      // 检查是否有强制更新 用于Legacy Suspense
      if ((current.flags & ForceUpdateForLegacySuspense) !== NoFlags) {
        didReceiveUpdate = true;
      } else {
        didReceiveUpdate = false;
      }
    }
  } else {
    // 没有旧Fiber,是首次渲染
    didReceiveUpdate = false;

    // 处理Hydration相关逻辑
    if (getIsHydrating() && isForkedChild(workInProgress)) {
      const slotIndex = workInProgress.index;
      const numberOfForks = getForksAtLevel(workInProgress);
      pushTreeId(workInProgress, numberOfForks, slotIndex);
    }
  }
  
  // 重置工作 Fiber 的 lanes
  workInProgress.lanes = NoLanes;
  switch (workInProgress.tag) {
    // 根据不同的tag调用不同的方法
    case FunctionComponent: {
      const Component = workInProgress.type;
      return updateFunctionComponent(
        current,
        workInProgress,
        Component,
        workInProgress.pendingProps,
        renderLanes,
      );
    }
    case ClassComponent: {
      const Component = workInProgress.type;
      const unresolvedProps = workInProgress.pendingProps;
      const resolvedProps = resolveClassComponentProps(
        Component,
        unresolvedProps,
      );
      return updateClassComponent(
        current,
        workInProgress,
        Component,
        resolvedProps,
        renderLanes,
      );
    }
    /** 等等其他类型组件处理 */
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76

# updateFunctionComponent

updateFunctionComponent函数是React中处理函数组件的更新逻辑。它负责调用函数组件的渲染函数,处理hooks,对比props是否有变化,以及协调子节点的更新。

function updateFunctionComponent(
  current, // 当前Fiber节点
  workInProgress, // 正在构建的Fiber节点
  Component, // 函数组件本身
  nextProps, // 组件的新props
  renderLanes // 当前渲染的优先级车道
) {
  // 准备读取上下文,确保组件可以访问到最新的上下文值
  prepareToReadContext(workInProgress);
  // 执行组件函数并处理Hooks,返回值React元素
  Component = renderWithHooks(
    current,
    workInProgress,
    Component,
    nextProps,
    void 0,
    renderLanes
  );
  // 检查渲染ID Hook
  nextProps = checkDidRenderIdHook();

  // 提前退出优化
  if (null !== current && !didReceiveUpdate)
    return (
      bailoutHooks(current, workInProgress, renderLanes),
      bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes)
    );
  // 处理Hydration   
  isHydrating && nextProps && pushMaterializedTreeId(workInProgress);
  // 标记更新
  workInProgress.flags |= 1;
  // 协调子节点
  reconcileChildren(current, workInProgress, Component, renderLanes);
  // 返回第一个Fiber子节点,继续Fiber遍历过程
  return workInProgress.child;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

# renderWithHooks

renderWithHooks函数是React执行函数组件的核心入口,负责设置Hooks执行环境,调用组件函数,处理渲染阶段的更新,并返回组件渲染结果。

function renderWithHooks(
  current,
  workInProgress,
  Component,
  props,
  secondArg,
  nextRenderLanes
) {
  // 设置Hooks执行环境
  renderLanes = nextRenderLanes;
  currentlyRenderingFiber = workInProgress;
  workInProgress.memoizedState = null;
  workInProgress.updateQueue = null;
  workInProgress.lanes = 0;
  // 设置 Hooks分发器
  ReactSharedInternals.H =
    null === current || null === current.memoizedState
      ? HooksDispatcherOnMount
      : HooksDispatcherOnUpdate;
  // 执行组件函数:生产环境禁用双重调用,开发模式下,双重调用组件函数以检测副作用    
  shouldDoubleInvokeUserFnsInHooksDEV = !1;
  nextRenderLanes = Component(props, secondArg);
  shouldDoubleInvokeUserFnsInHooksDEV = !1;
  // 处理渲染阶段的更新:在渲染过程中调用setState或者useReducer的dispatch
  didScheduleRenderPhaseUpdateDuringThisPass &&
    (nextRenderLanes = renderWithHooksAgain(
      workInProgress,
      Component,
      props,
      secondArg
    ));
  // 完成Hooks渲染:清理执行环境等  
  finishRenderingHooks(current);
  return nextRenderLanes;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
编辑 (opens new window)
上次更新: 2026/03/13, 10:06:03
最近更新
01
effect
03-29
02
会动的png
03-24
03
React19 useOptimistic hooks介绍
03-19
更多文章>
Theme by Vdoing | Copyright © 2024-2026 东流 | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式