React16源码: React中的beginWork的源码实现

React render阶段解析二-beginWork流程 这次是接着上一期render阶段的文章,解析挂载时render阶段的"递"阶段----beginWork函数 beginWork的调用 performUnitOfWork函数内部执行beginWork的函数 // ProfileMode 模式下,猜测和性能分析相关 if (enableProfilerTimer && (unitOfWork.mode & ProfileMode) !== NoMode) { startProfilerTimer(unitOfWork); 阅读详情

beginWork


1 )概述

  • 在 renderRoot 之后,要对我们的 Fiber 树每一个节点进行对应的更新
  • 更新节点的一个入口方法,就是 beginWork
  • 这个入口方法会有帮助我们去优化整棵树的更新过程
    • react 它的节点其实是非常多的,如果每一次子节点的一个更新
    • 就需要每一个节点都执行一遍更新的话,它整体的性能肯定会不好,而且是没有必要的
    • 我们一个子节点的更新,可能不会影响到它的兄弟节点的更新
    • 所以这部分肯定是要优化的
  • 具体它是如何进行优化的,如下
    • 首先,要判断组件的更新是否可以优化
    • 然后要根据节点的类型分发进行处理,每一个节点它的更新方式会不一样
    • 最后是要根据 expirationTime 等信息判断这个节点的更新是否可以跳过

2 )源码

  • 在 renderRoot 中,它里面调用一个方法叫做 workLoop
  • 在 workLoop 中调用的一个方法叫做 performUnitOfWork
  • 而 beginWork 方法就在 performUnitOfWork 中调用
  • beginWork 就是执行对整棵树的每一个节点进行更新的一个操作
  • beginWork 来自于
    import {beginWork} from './ReactFiberBeginWork';
    

定位到 packages/react-reconciler/src/ReactFiberBeginWork.js
整个文件 export 出去的只有 beginWork 方法

function beginWork(
  current: Fiber | null,
  workInProgress: Fiber,
  renderExpirationTime: ExpirationTime,
): Fiber | null {
  // 读取了 workInProgress.expirationTime 这个值,这个 expirationTime 是节点上的 expirationTime
  // 函数第三个参数 renderExpirationTime 是 nextExpirationTimeToWorkOn 和 下面这个 expirationTime 有区别
  const updateExpirationTime = workInProgress.expirationTime;
  // 在 ReactDOM.render 第一次渲染时,第一个节点 current 是有值的, 接下去的节点都是没有的
  // 因为我们操作都是在 workInProgress 上操作的
  // 所以,workInProgress 创建的 child 节点也是一个 workInProgress 而不是 current
  // performUnitOfWork 接收的就是 workInProgress
  if (current !== null) {
    const oldProps = current.memoizedProps;
    const newProps = workInProgress.pendingProps;
    // 下面 renderExpirationTime 标志优先级最大都到哪个点,如果节点上的 expirationTime 比 renderExpirationTime 小
    // 说明节点上有优先级更高的任务,在这次渲染里是会执行的,反之,则不需要进行渲染,这个节点可以跳过
    // (updateExpirationTime === NoWork || updateExpirationTime > renderExpirationTime) 代表没有更新 或 有更新,但是优先级不高
    // hasLegacyContextChanged 属 context 相关api, childContextType 先跳过
    // oldProps === newProps 表示 props 一样
    if (
      oldProps === newProps &&
      !hasLegacyContextChanged() &&
      (updateExpirationTime === NoWork ||
        updateExpirationTime > renderExpirationTime)
    ) {
      // This fiber does not have any pending work. Bailout without entering
      // the begin phase. There's still some bookkeeping we that needs to be done
      // in this optimized path, mostly pushing stuff onto the stack.
      // switch 先跳过
      switch (workInProgress.tag) {
        case HostRoot:
          pushHostRootContext(workInProgress);
          resetHydrationState();
          break;
        case HostComponent:
          pushHostContext(workInProgress);
          break;
        case ClassComponent: {
          const Component = workInProgress.type;
          if (isLegacyContextProvider(Component)) {
            pushLegacyContextProvider(workInProgress);
          }
          break;
        }
        case HostPortal:
          pushHostContainer(
            workInProgress,
            workInProgress.stateNode.containerInfo,
          );
          break;
        case ContextProvider: {
          const newValue = workInProgress.memoizedProps.value;
          pushProvider(workInProgress, newValue);
          break;
        }
        case Profiler:
          if (enableProfilerTimer) {
            workInProgress.effectTag |= Update;
          }
          break;
        case SuspenseComponent: {
          const state: SuspenseState | null = workInProgress.memoizedState;
          const didTimeout = state !== null && state.didTimeout;
          if (didTimeout) {
            // If this boundary is currently timed out, we need to decide
            // whether to retry the primary children, or to skip over it and
            // go straight to the fallback. Check the priority of the primary
            // child fragment.
            const primaryChildFragment: Fiber = (workInProgress.child: any);
            const primaryChildExpirationTime =
              primaryChildFragment.childExpirationTime;
            if (
              primaryChildExpirationTime !== NoWork &&
              primaryChildExpirationTime <= renderExpirationTime
            ) {
              // The primary children have pending work. Use the normal path
              // to attempt to render the primary children again.
              return updateSuspenseComponent(
                current,
                workInProgress,
                renderExpirationTime,
              );
            } else {
              // The primary children do not have pending work with sufficient
              // priority. Bailout.
              const child = bailoutOnAlreadyFinishedWork(
                current,
                workInProgress,
                renderExpirationTime,
              );
              if (child !== null) {
                // The fallback children have pending work. Skip over the
                // primary children and work on the fallback.
                return child.sibling;
              } else {
                return null;
              }
            }
          }
          break;
        }
      }
      // 这个方法跳过该节点与其所有子节点的更新
      return bailoutOnAlreadyFinishedWork(
        current,
        workInProgress,
        renderExpirationTime,
      );
    }
  }
  
  // Before entering the begin phase, clear the expiration time.
  workInProgress.expirationTime = NoWork;
  // 如果节点有更新,通过节点的 tag,执行不同的方法,进行组件的更新
  switch (workInProgress.tag) {
    case IndeterminateComponent: {
      const elementType = workInProgress.elementType;
      return mountIndeterminateComponent(
        current,
        workInProgress,
        elementType,
        renderExpirationTime,
      );
    }
    case LazyComponent: {
      const elementType = workInProgress.elementType;
      return mountLazyComponent(
        current,
        workInProgress,
        elementType,
        updateExpirationTime,
        renderExpirationTime,
      );
    }
    case FunctionComponent: {
      const Component = workInProgress.type;
      const unresolvedProps = workInProgress.pendingProps;
      const resolvedProps =
        workInProgress.elementType === Component
          ? unresolvedProps
          : resolveDefaultProps(Component, unresolvedProps);
      return updateFunctionComponent(
        current,
        workInProgress,
        Component,
        resolvedProps,
        renderExpirationTime,
      );
    }
    case ClassComponent: {
      const Component = workInProgress.type;
      const unresolvedProps = workInProgress.pendingProps;
      const resolvedProps =
        workInProgress.elementType === Component
          ? unresolvedProps
          : resolveDefaultProps(Component, unresolvedProps);
      return updateClassComponent(
        current,
        workInProgress,
        Component,
        resolvedProps,
        renderExpirationTime,
      );
    }
    case HostRoot:
      return updateHostRoot(current, workInProgress, renderExpirationTime);
    case HostComponent:
      return updateHostComponent(current, workInProgress, renderExpirationTime);
    case HostText:
      return updateHostText(current, workInProgress);
    case SuspenseComponent:
      return updateSuspenseComponent(
        current,
        workInProgress,
        renderExpirationTime,
      );
    case HostPortal:
      return updatePortalComponent(
        current,
        workInProgress,
        renderExpirationTime,
      );
    case ForwardRef: {
      const type = workInProgress.type;
      const unresolvedProps = workInProgress.pendingProps;
      const resolvedProps =
        workInProgress.elementType === type
          ? unresolvedProps
          : resolveDefaultProps(type, unresolvedProps);
      return updateForwardRef(
        current,
        workInProgress,
        type,
        resolvedProps,
        renderExpirationTime,
      );
    }
    case Fragment:
      return updateFragment(current, workInProgress, renderExpirationTime);
    case Mode:
      return updateMode(current, workInProgress, renderExpirationTime);
    case Profiler:
      return updateProfiler(current, workInProgress, renderExpirationTime);
    case ContextProvider:
      return updateContextProvider(
        current,
        workInProgress,
        renderExpirationTime,
      );
    case ContextConsumer:
      return updateContextConsumer(
        current,
        workInProgress,
        renderExpirationTime,
      );
    case MemoComponent: {
      const type = workInProgress.type;
      const unresolvedProps = workInProgress.pendingProps;
      const resolvedProps = resolveDefaultProps(type.type, unresolvedProps);
      return updateMemoComponent(
        current,
        workInProgress,
        type,
        resolvedProps,
        updateExpirationTime,
        renderExpirationTime,
      );
    }
    case SimpleMemoComponent: {
      return updateSimpleMemoComponent(
        current,
        workInProgress,
        workInProgress.type,
        workInProgress.pendingProps,
        updateExpirationTime,
        renderExpirationTime,
      );
    }
    case IncompleteClassComponent: {
      const Component = workInProgress.type;
      const unresolvedProps = workInProgress.pendingProps;
      const resolvedProps =
        workInProgress.elementType === Component
          ? unresolvedProps
          : resolveDefaultProps(Component, unresolvedProps);
      return mountIncompleteClassComponent(
        current,
        workInProgress,
        Component,
        resolvedProps,
        renderExpirationTime,
      );
    }
    default:
      invariant(
        false,
        'Unknown unit of work tag. This error is likely caused by a bug in ' +
          'React. Please file an issue.',
      );
  }
}
  • 注意,最顶层 workInProgress.expirationTime; 这个 expirationTime Fiber 节点上的 expirationTime
    • 对比 ReactFiberScheduler.js 中的 renderRoot 中读取的 root.nextExpirationTimeToWorkOn
    • 这个 root 是 FiberRoot, 而 FiberRoot 对应的 Fiber对象是 RootFiber
    • RootFiber 是 FiberRoot 的 current 属性,它没有对应React组件树的任何节点, 它只对应 FiberRoot 节点
      • FiberRoot 节点也就是挂载整个应用到的 Dom 节点
      • FiberRoot 上面存储整个应用的 expirationTime 和
    • RootFiber 的 stateNode 属性是 FiberRoot
    • FiberRoot 上面会存储整个应用上面的 expirationTime 和 nextExpirationTimeToWorkOn
    • 上面的两个值意义是不一样的, 在 renderRoot 函数中的一段代码如下
      // Reset the stack and start working from the root.
      resetStack();
      nextRoot = root;
      nextRenderExpirationTime = expirationTime;
      // nextUnitOfWork 是一个Fiber对象, 对应 RootFiber, 而非 FiberRoot
      // 更新过程使用的都是 Fiber 对象,不会是 FiberRoot
      nextUnitOfWork = createWorkInProgress(
        nextRoot.current, // 注意这里
        null,
        nextRenderExpirationTime,
      );
      
      • nextUnitOfWork 才是我们每一个节点去更新时要操作的节点对象
    • 所以,workInProgress.expirationTime 是对应Fiber节点产生更新的过期时间
      • 这里页面点击按钮让某个组件更新,最多到App上面创建更新
      • 不可能到 RootFiber 上面创建更新
    • 而 RootFiber 产生更新时在 ReactDOM.render 的时候才会有
    • 注意,在 beginWork 第一个参数是 current 是 Fiber对象,它对应的tag是 HostRoot
      • 在创建 FibeRoot 时, 在 ReactFiberReconciler.js 中的 createContainer 中
      • 有一个方法叫做 createFiberRoot, 定位到 ReactFiberRoot.js 中
      • 定位到 createHostRootFiber 方法,而这个方法又来自于 ReactFiber.js
      • 找到 createFiber, 是最终创建Fiber对象的时候调用的方法
        return createFiber(HostRoot, null, null, mode);
        
      • 参数是 HostRoot, null, null, mode
      • 第一个参数 HostRoot 就是 Fiber的tag
    • 在 ReactFiberScheduler.js 中 performUnitOfWork 接收的就是一个 workInProgress
      • 它传给 beginWork 的第一个参数 current 是 workInProgress.alternate
      • 在第一次渲染,也就是 ReactDOM.render 的时候, workInProgress 是刚刚创建的
      • 是不会在创建一个 current, 要等渲染结束后,把 current 和 workInProgress 的指针进行一个调换
      • 它才会变成有 current, 没有 workInProgress,再下次有更新产生,进行渲染时,才会创建一个新的 workInProgress
      • 这时候,current 和 workInProgress 都有了
      • 在最顶层 判断 current 是否 为 null, 也就是 判断是否是第一次渲染
  • 关于 bailoutOnAlreadyFinishedWork 这个方法帮助跳过该节点与其所有子节点的更新
    function bailoutOnAlreadyFinishedWork(
      current: Fiber | null,
      workInProgress: Fiber,
      renderExpirationTime: ExpirationTime,
    ): Fiber | null {
      cancelWorkTimer(workInProgress);
    
      if (current !== null) {
        // Reuse previous context list
        workInProgress.firstContextDependency = current.firstContextDependency;
      }
    
      if (enableProfilerTimer) {
        // Don't update "base" render times for bailouts.
        stopProfilerTimerIfRunning(workInProgress);
      }
    
      // Check if the children have any pending work.
      const childExpirationTime = workInProgress.childExpirationTime; // 这个值是 React 16.5 加上的,更早跳过更新
      // 子树上无更新,或高优先级任务在这次渲染中完成的 则跳过,是一个非常大的优化
      if (
        childExpirationTime === NoWork ||
        childExpirationTime > renderExpirationTime
      ) {
        // The children don't have any work either. We can skip them.
        // TODO: Once we add back resuming, we should check if the children are
        // a work-in-progress set. If so, we need to transfer their effects.
        return null;
      } else {
        // This fiber doesn't have work, but its subtree does. Clone the child
        // fibers and continue.
        // 如果子树上有更新要执行,拷贝老的child
        cloneChildFibers(current, workInProgress);
        return workInProgress.child;
      }
    }
    
    • 回过头看 performUnitOfWork, return 了 child 之后,赋值给next
      let next;
      if (enableProfilerTimer) {
        // ... 跳过很多代码
        next = beginWork(current, workInProgress, nextRenderExpirationTime);
        // ... 跳过很多代码
      } else {
        next = beginWork(current, workInProgress, nextRenderExpirationTime);
        workInProgress.memoizedProps = workInProgress.pendingProps;
      }
      
      // ... 跳过很多代码
      
      if (next === null) {
        // If this doesn't spawn new work, complete the current work.
        next = completeUnitOfWork(workInProgress);
      }
      
      ReactCurrentOwner.current = null;
      // next 不为 null, 直接 return
      return next;
      
    • return next; 之后 回调 workLoop, 之后赋值给 nextUnitOfWork
      while (nextUnitOfWork !== null) {
          nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
        }
      
    • 通过 while 循环继续执行 child 的更新
    • 这就是循环能够成立的条件
  • 回到 beginWork 中当节点还有更新的时候,执行 switch case
    • 通过节点类型执行不同的方法来进行组件的更新
    • 比如 FunctionComponent, MemoComponent 等
React 源码解析 | Reconcile协调过程 上篇讲了React的工作流程,这篇详细的讲一下render过程中的beginWork函数,也就是深度优先创建Fiber树中"递"的过程。beginWork函数传入当前已经创建好的Fiber节点,返回创建/复用的第一个子FIber节点,也就是wip.child在renderRoot中,在开始创建整棵FIber树之前,会先调用prepareRefreshStack创建/复用一个新的HostRootFiber。 阅读详情

相关推荐

【React源码 - Fiber架构之Reconciler】

React源码-Fiber架构之Reconciler

weixin_44273311的博客 2124

React 第三十九章 beginWork工作流程

beginWork 方法主要是根据传入的 FiberNode 创建下一级的 FiberNode。整个 beginWork 方法的流程如下图所示:首先在 beginWork 中,会判断当前的流程是 mount(初次渲染)还是update(更新),判断的依据就是 currentFiberNode 是否存在无法复用的 update 流程和 mount 流程大体一致,主要区别在于是否会生成带副作用标记 flags 的 FiberNode不同的 FiberNode,会有不同的 tag。

aXin_li的博客 1223

从论文到生产:iSLIP优先级匹配算法在SDN交换机中的20年演进史

本文回顾了iSLIP优先级匹配算法在SDN交换机中的20年演进历程,从斯坦福大学的原始论文到现代芯片实现。通过独特的指针滑动和迭代循环机制,iSLIP算法显著提升了交换机的吞吐量和公平性,解决了传统FIFO调度的队头阻塞问题。文章详细探讨了算法在硬件实现中的工程挑战、开源实践及未来AI时代的智能调度方向。

weixin_29230649的博客 331

React源码解析18(9)------ 实现多节点渲染【修改beginWork和completeWork】

目前,我们已经实现了单节点的,beginWork,completeWork,diff流程。之前的children就直接是一个对象jsx,因为是单节点。而现在,是通过数组的方式表示。})]})]})

weixin_46726346的博客 855

Android Audio - 支持多应用同时录音_Android8.1修改方法

支持多应用同时录音_Android8.1修改方法 源码路径: sdk\frameworks\av\services\audiopolicy\managerdefault\AudioPolicyManager.cpp 需要修改两个位置: audio_io_handle_t AudioPolicyManager::getInputForDevice() 在mpClientInterface-&gt...

iFinelio Tower 的博客 5759

Backblaze 2025全年硬盘故障率报告解读

作为长期追踪存储行业动态的科技博主,每年/季度Backblaze的Drive Stats报告都是我重点关注的核心内容——不同于厂商发布的实验室数据,Backblaze以近13年、数十万片企业级硬盘的真实运行数据为基础,其年化故障率(AFR)、寿命趋势等结论,直接反映了硬盘在严苛数据中心环境下的真实表现,无论是企业存储选型还是个人高端存储参考,都具备极高的实用价值。2025年末,Backblaze发布了第13年的年度收官报告,涵盖2025年Q4、全年及终身硬盘可靠性数据。

存储随笔 4021

react源码分析(5)-介绍beginWork

目录 2021SC@SDUSC beginWork的执行过程 谈谈其中的updateClassComponent方法 关于bailoutOnAlreadyFinishedWork DIFF算法的入口 总结 2021SC@SDUSC beginWork的执行过程 谈谈beginWork,react所需要调度的就是Fiber树的构建与更新,所以我们从beginWork开始,它被从ReactFiberBeginWork.new.js中引入,而在beginWork中会比较current树中..

weixin_45668912的博客 615

ADS笔记,新旧两组仿真数据进行绘图和列表对比

原理图器件参数的不同,怎么进行对比观看,操作如下。

彭辉荣的博客 3871

React 的源码与原理解读(五):beginWork 分类处理逻辑

本节的我们将从 上一节留下的问题出发,谈谈 **beginWork ()** 中怎么样把一个 element 节点变成一个 fiber 结点,其中我们会提到我们的 **beginwork 怎么样处理更新和首次渲染**,通过什么样的方式来加速渲染,以及**对于不同类型的节点使用怎么样不同的逻辑**

weixin_46463785的博客 1018

KEPServerEX 6 之 lot Gateway MQTT Clinet 配置使用方式

IoT Gateway即Internet of Things Gateway物联网网关。 ---------------------------------------------------------------------------------- 方式:使用kepw的IOTGateway插件选择MQTTClient 解决:可以实现 KEPW 的Tag值 发送到 MQTT 服务器上 ----------------------------------------...

-雲飛兄-博客 6942

第5.2章 【自动驾驶行业融合定位核心】:手把手详解ESKF(误差卡尔曼滤波)理论公式及代码

自动驾驶定位中的ESKF(误差卡尔曼滤波)技术是解决IMU累积误差的关键,通过分离名义状态与误差状态实现高精度定位。其核心步骤包括:1)名义状态递推(位置/速度/姿态的基础物理计算);2)误差传播建模(雅可比矩阵F量化误差影响);3)协方差更新(评估定位不确定性)。ESKF在GNSS信号丢失(如隧道场景)、无卫星定位(地下车库)等场景发挥重要作用,通过融合多传感器数据维持定位精度。工程实现需解决零偏校准、协方差投影等关键问题,噪声参数需通过数据标定而非随意设置。掌握ESKF原理与实现是自动驾驶定位工程师的核

行知SLAM 707

React16源码: React中处理hydrate的核心流程源码实现

如果不能找到,就对这节点以及它的子树停止一个 hydrate 的流程,然后设置一些全局变量。在 beginWork 的流程当中,去判断更新的一个 HostComponent。是否可以从 hydrate 的 dom 节点当中去找到一个可以复用的节点。方法标志着整个 react 应用的 hydrate 过程的一个开启。第4个参数 forceHydrate 表示是否强制融合。接下去走的流程是在 completeUnitOfWork。开始了之后要做的是什么呢?

Wang的专栏 1584

PCL RANSAC拟合分割多条直线【2026最新版】

使用RANSAC算法拟合分割多条直线,输出每一条直线的拟合参数到控制台,并保存直线点云到本地文件夹。博客长期更新,本文最新更新时间为:2026年5月24日。

点云侠的博客 7975

React16源码: React中的renderRoot的源码实现

renderRoot 是一个非常复杂的方法, 它调用 workLoop 进行循环单元更新, 并且捕获错误并进行处理,最后,在走完流程之后要进行善后

Wang的专栏 1397

从零开始学Agent的搭建——多角色项目需求分析框架实战

场景一:电商促销需求——技术细节顾此失彼团队用单Agent分析一个"双11秒杀系统"的需求。Agent输出了完整的功能清单,但当我们拿着这份方案找架构师评审时,发现了致命问题:Agent完全没有考虑库存扣减的并发一致性、Redis与MySQL之间的数据同步延迟、以及超卖风险的控制策略。原因是单Agent在处理"业务理解"任务时,已经耗尽了它的"注意力预算",技术深度分析几乎为空。场景二:ERP集成需求——跨系统边界模糊。

软件行业技术文化交流。 536

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

React16源码: React中的FunctionComponent的源码实现

定位到 packages/react-reconciler/src/ReactFiberBeginWork.js。的 beginWork 函数,在 beginWork 下面的 执行 switch case 中。进入到 updateFunctionComponent 方法。

Wang的专栏 969

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

React16源码: React中的reconcileChildren的源码实现

在更新了一个节点之后,拿到它的props.children, 要根据这个children里面的 ReactElement 来去创建子树的所有的 fiber 对象, 要根据 props.children 来生成 fiber 子树,然后判断 fiber 对象它是否是可以复用的

Wang的专栏 2133

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

React16源码: React中context-stack的源码实现

如果在没有理清楚之前的整一个react的更新的过程的时候就来讲这些PI呢可能会让大家很难去理解这部分内容。context内部有一个概念是 stack, 有一个唯一的stack,里面保存各种各样的东西。react是一个非常纯粹的框架, 它的纯粹体现在哪里?所以呢我单独把它放到我们整个核心环节的后面。

Wang的专栏 1309

React 16.12.0 源码解读(二)之任务调度

React任务调度部分的源码梳理和解读。

Babyfaceqian的博客 257

react源码解析-debugger阶段-类组件mount阶段的beginWork

类组件的beginWork。 Appfiber执行完递阶段之后,轮到DDfiber执行递解端。 对于类组件,在beginWork的时候,会调用updateClassComponent方法。 类组件的fiber如: { alternate: null child: null elementType: ƒ DD() key: null lanes: 16 mode: 1 pendingProps: {} ref: null return: FiberNode {tag: 0, key: null, stateN

lin_fightin的博客 1213

React 16 源码解析笔记 05 - render阶段03 workLoopSync 解析

workLoopSync 解析 上面已经把 workInProgress Fiber 树中的 rootFiber 构建完成,接下来要构建它的子级 fiber 对象了。 这个子级 fiber 对象就是 render 方法的第一个参数,它在代码走到 workLoopSync 方法时开始被构建。 workLoopSync 就是开启一个循环,以同步的方式开始构建 fiber 对象 workLoopSync workLoopSync 仅仅开启了一个 while 循环,用于构建 rootFiber 对象的所有子级 fi

皮蛋很白的博客 735

【React源码08】深入学习React 源码实现——Fiber架构双缓冲(current 与 workInProgress)机制

React的双缓冲机制(current与workInProgress)是Fiber架构的核心特性,通过两棵Fiber树的交替使用实现高效的UI更新。在更新过程中,React基于current树创建workInProgress树,所有更新操作在workInProgress树上进行,完成后通过commitRoot提交并切换指针。这种机制允许React保留当前状态,并支持中断/恢复渲染。源码中createWorkInProgress函数负责节点的创建/复用,通过alternate指针实现双树快速切换。

silverclayz的技术分享 944

react源码解析8.render阶段

react源码解析8.render阶段 视频课程(高效学习):进入课程 课程目录: 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.c

bemystery的博客 264

React 16.7 Fiber源码解读 (二)之运行流程

Fiber Debugger Fiber Debugger是React官方的一个图形化展示fiber运行过程的动态demo. 点击Edit按钮,可将以下代码复制到编辑框,点击运行Run即可查看 log('Render &amp;amp;amp;amp;amp;amp;amp;lt;div&amp;amp;amp;amp;amp;amp;amp;gt;Hello&amp;amp;amp;amp;amp;amp;amp;lt;/div&amp;amp;amp;amp;amp;am

辰辰沉沉大辰沉 3046
上一篇: React16源码: React中requestCurrentTime和expirationTime的源码实现补充
下一篇: React16源码: React中的FunctionComponent的源码实现
Wang's Blog
博客等级 码龄12年 7434粉丝 2421原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wang's Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值