React16源码: React中commit阶段的commitAllLifeCycles的源码实现

YOLOv11官方代码库与预训练模型下载:介绍Ultralytics官方GitHub及模型权重(yolov11n.pt, yolov11s.pt等) 本文介绍了Ultralytics官方GitHub仓库和YOLOv11预训练模型。Ultralytics仓库是YOLO系列算法的官方实现,包含YOLOv11最新代码、预训练模型、文档和工具。仓库采用清晰的代码结构和活跃的更新策略,支持全流程开发。YOLOv11提供了5种不同规模的模型变体(YOLOv11n/s/m/l/x),在精度、速度和模型大小间权衡,适用于从移动设备到高精度检测等不同场景。各模型在COCO数据集上预训练,可直接使用或微调,满足多样化应用需求。 阅读详情

commitAllLifeCycles


1 )概述

  • 在 react commit 阶段的 commitRoot 第三个 while 循环中
  • 处理了生命周期相关的一些内容
  • 它这个方法的名字叫做 commitAllLifeCycles

2 )源码

定位到 packages/react-reconciler/src/ReactFiberScheduler.js#L479

查看 commitAllLifeCycles

function commitAllLifeCycles(
  finishedRoot: FiberRoot,
  committedExpirationTime: ExpirationTime,
) {
  if (__DEV__) {
    ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings();
    ReactStrictModeWarnings.flushLegacyContextWarning();

    if (warnAboutDeprecatedLifecycles) {
      ReactStrictModeWarnings.flushPendingDeprecationWarnings();
    }
  }
  // 通过遍历 firstEffect 到 lastEffect 的单项链表,基于每一个effect对应的fiber对象,对它做出对应的操作
  while (nextEffect !== null) {
    const effectTag = nextEffect.effectTag;
    // 这边的操作设置的是 update 和 callback ,如果有 Update | Callback 就执行 commitLifeCycles
    if (effectTag & (Update | Callback)) {
      recordEffect();
      const current = nextEffect.alternate;
      commitLifeCycles(
        finishedRoot,
        current,
        nextEffect,
        committedExpirationTime,
      );
    }

    if (effectTag & Ref) {
      recordEffect();
      commitAttachRef(nextEffect);
    }

    if (enableHooks && effectTag & Passive) {
      rootWithPendingPassiveEffects = finishedRoot;
    }

    nextEffect = nextEffect.nextEffect;
  }
}
  • 进入 commitLifeCycles

    function commitLifeCycles(
      finishedRoot: FiberRoot,
      current: Fiber | null,
      finishedWork: Fiber,
      committedExpirationTime: ExpirationTime,
    ): void {
      // 根据不同的组件类型来执行不同的操作
      switch (finishedWork.tag) {
        case FunctionComponent:
        case ForwardRef:
        case SimpleMemoComponent: {
          commitHookEffectList(UnmountLayout, MountLayout, finishedWork);
          break;
        }
        // 主要是 ClassComponent,它会根据 current 是否等于 null 来执行不同的生命周期方法
        // 一个是 componentDidMount 跟 componentDidUpdate
        // 因为我们只有在第一次渲染的时候才会调用 componentDidMount 这个生命周期方法
        // 后续调用的都是 componentDidUpdate 它们的调用方式会有一定的区别
        // 这里是 ClassComponent 它的一个commit的过程
        case ClassComponent: {
          const instance = finishedWork.stateNode;
          if (finishedWork.effectTag & Update) {
            // 第一次调用
            if (current === null) {
              startPhaseTimer(finishedWork, 'componentDidMount');
              // We could update instance props and state here,
              // but instead we rely on them being set during last render.
              // TODO: revisit this when we implement resuming.
              if (__DEV__) {
                if (finishedWork.type === finishedWork.elementType) {
                  warning(
                    instance.props === finishedWork.memoizedProps,
                    'Expected instance props to match memoized props before ' +
                      'componentDidMount. This is likely due to a bug in React. ' +
                      'Please file an issue.',
                  );
                  warning(
                    instance.state === finishedWork.memoizedState,
                    'Expected instance state to match memoized state before ' +
                      'componentDidMount. This is likely due to a bug in React. ' +
                      'Please file an issue.',
                  );
                }
              }
              instance.componentDidMount();
              stopPhaseTimer();
            } else {
              // 更新
              const prevProps =
                finishedWork.elementType === finishedWork.type
                  ? current.memoizedProps
                  : resolveDefaultProps(finishedWork.type, current.memoizedProps);
              const prevState = current.memoizedState;
              startPhaseTimer(finishedWork, 'componentDidUpdate');
              // We could update instance props and state here,
              // but instead we rely on them being set during last render.
              // TODO: revisit this when we implement resuming.
              if (__DEV__) {
                if (finishedWork.type === finishedWork.elementType) {
                  warning(
                    instance.props === finishedWork.memoizedProps,
                    'Expected instance props to match memoized props before ' +
                      'componentDidUpdate. This is likely due to a bug in React. ' +
                      'Please file an issue.',
                  );
                  warning(
                    instance.state === finishedWork.memoizedState,
                    'Expected instance state to match memoized state before ' +
                      'componentDidUpdate. This is likely due to a bug in React. ' +
                      'Please file an issue.',
                  );
                }
              }
              instance.componentDidUpdate(
                prevProps,
                prevState,
                instance.__reactInternalSnapshotBeforeUpdate, // 在 commitRoot 的方法里面去生成的 instance 对象上面的 snapshot 快照
              );
              stopPhaseTimer();
            }
          }
          const updateQueue = finishedWork.updateQueue;
          if (updateQueue !== null) {
            if (__DEV__) {
              if (finishedWork.type === finishedWork.elementType) {
                warning(
                  instance.props === finishedWork.memoizedProps,
                  'Expected instance props to match memoized props before ' +
                    'processing the update queue. This is likely due to a bug in React. ' +
                    'Please file an issue.',
                );
                warning(
                  instance.state === finishedWork.memoizedState,
                  'Expected instance state to match memoized state before ' +
                    'processing the update queue. This is likely due to a bug in React. ' +
                    'Please file an issue.',
                );
              }
            }
            // We could update instance props and state here,
            // but instead we rely on them being set during last render.
            // TODO: revisit this when we implement resuming.
            // 对于 ClassComponent,还需要做一件事情,就是去获取它的 updatequeen
            // 然后 执行 commitUpdateQueue 这么一个方法,我们要拿到他的 props
            commitUpdateQueue(
              finishedWork,
              updateQueue,
              instance,
              committedExpirationTime,
            );
          }
          return;
        }
        // 对于 HostRoot,它也会执行 commitUpdateQueue
        // 因为对于 HostRoot 来说,基本上只有在调用 ReactDOM.render 的时候才会创建update
        // 它的 commitUpdateQueue, 能做什么呢?对于调用 ReactDOM.render 是可以传3个参数的
        // 第3个参数就是在第一次 render 结束之后,它的一个回调, 执行过程类似
        case HostRoot: {
          const updateQueue = finishedWork.updateQueue;
          if (updateQueue !== null) {
            let instance = null;
            // 注意这里,有子树的场景
            if (finishedWork.child !== null) {
              switch (finishedWork.child.tag) {
                // 这里
                case HostComponent:
                  instance = getPublicInstance(finishedWork.child.stateNode); // 获取 对应 HostComponent 的 dom 节点,就是返回传参
                  break;
                // 这里,其实和上面一样
                case ClassComponent:
                  instance = finishedWork.child.stateNode;
                  break;
              }
            }
            commitUpdateQueue(
              finishedWork,
              updateQueue,
              instance,
              committedExpirationTime,
            );
          }
          return;
        }
        case HostComponent: {
          const instance: Instance = finishedWork.stateNode;
    
          // Renderers may schedule work to be done after host components are mounted
          // (eg DOM renderer may schedule auto-focus for inputs and form controls).
          // These effects should only be committed when components are first mounted,
          // aka when there is no current/alternate.
          // 参考下面的 commitMount 注释
          if (current === null && finishedWork.effectTag & Update) {
            const type = finishedWork.type;
            const props = finishedWork.memoizedProps;
            commitMount(instance, type, props, finishedWork);
          }
    
          return;
        }
        case HostText: {
          // We have no life-cycles associated with text.
          return;
        }
        case HostPortal: {
          // We have no life-cycles associated with portals.
          return;
        }
        case Profiler: {
          if (enableProfilerTimer) {
            const onRender = finishedWork.memoizedProps.onRender;
    
            if (enableSchedulerTracing) {
              onRender(
                finishedWork.memoizedProps.id,
                current === null ? 'mount' : 'update',
                finishedWork.actualDuration,
                finishedWork.treeBaseDuration,
                finishedWork.actualStartTime,
                getCommitTime(),
                finishedRoot.memoizedInteractions,
              );
            } else {
              onRender(
                finishedWork.memoizedProps.id,
                current === null ? 'mount' : 'update',
                finishedWork.actualDuration,
                finishedWork.treeBaseDuration,
                finishedWork.actualStartTime,
                getCommitTime(),
              );
            }
          }
          return;
        }
        case SuspenseComponent:
          break;
        case IncompleteClassComponent:
          break;
        default: {
          invariant(
            false,
            'This unit of work tag should not have side-effects. This error is ' +
              'likely caused by a bug in React. Please file an issue.',
          );
        }
      }
    }
    
    • 进入 commitUpdateQueue
      // packages/react-reconciler/src/ReactUpdateQueue.js#L571
      export function commitUpdateQueue<State>(
        finishedWork: Fiber,
        finishedQueue: UpdateQueue<State>,
        instance: any,
        renderExpirationTime: ExpirationTime,
      ): void {
        // If the finished render included captured updates, and there are still
        // lower priority updates left over, we need to keep the captured updates
        // in the queue so that they are rebased and not dropped once we process the
        // queue again at the lower priority.
      
        // 这里做了一个判断,是否有 firstCapturedUpdate,在 finishedqueen 上面, 也就是组件的 updateQueen 上面
        // 这个 updateQueue上面, 如果有 capturedupdate,就是说我们在渲染这个组件的子树的时候,如果有异常出现
        // 并且被这个组件捕获,会产生这部分的update, 这部分的update,有可能在这一次的渲染周期里面, 没有被执行完
        // 其实这部分它有一个用意,就是说对于被捕获的错误,我们如果在这一次渲染周期里面无法去处理
        // 没有办法去完成它,我们把它放到这个组件上面,如果它还有低优先级的更新的话
        // 那么我们把它放到低优先级的更新上面去看他是否在那个低优先级的更新上能够被处理
        // 如果我们没有低优先级的处理了, 如果我们没有低优先级的更新了
        // 我们在本次渲染当中捕获的更新,就直接给它清空了
        // 因为我们本次渲染里面没有完成,为了不影响之后产生的更新,我们就直接清空它了
        // 而不需要去让它在后续影响整个组件的一个更新过程
        if (finishedQueue.firstCapturedUpdate !== null) {
          // Join the captured update list to the end of the normal list.
          // 这个时候它会进行一个判断, 如果我们现在这个组件上面还有 update 不是的 capturedUpdate, 而是普通的我们自己创建的update
          if (finishedQueue.lastUpdate !== null) {
            // 就把capturedupdate放到正常的update的后面,就把它在链表上面去给它接在最后面这一部分
            finishedQueue.lastUpdate.next = finishedQueue.firstCapturedUpdate;
            finishedQueue.lastUpdate = finishedQueue.lastCapturedUpdate;
          }
          // Clear the list of captured updates.
          // 不管有没有,我们都要执行,把firstCapturedUpdate到lastCapturedUpdate这个链表上面的数据清空
          finishedQueue.firstCapturedUpdate = finishedQueue.lastCapturedUpdate = null;
        }
      
        // Commit the effects
        // commitUpdateEffects 它不仅仅要对 firstEffect 来执行
        commitUpdateEffects(finishedQueue.firstEffect, instance);
        finishedQueue.firstEffect = finishedQueue.lastEffect = null;
      
        // 而同样的对于 capturedEffect 也要进行执行
        // 比如之前 workLoop 中看到过的 throw exception 里面
        // 去捕获了这个错误,然后为 classcomponent 创建了一个 update
        // throw exception 里面,在 unwindwork 中的 createClassErrorUpdate, 在里面 放入了update它的callback
        // 就是去调用 componentDidCatch 这个生命周期方法,这个callback 也是会在这个地方被执行的
        commitUpdateEffects(finishedQueue.firstCapturedEffect, instance);
        finishedQueue.firstCapturedEffect = finishedQueue.lastCapturedEffect = null;
      }
      
      • 进入 commitUpdateEffects
        function commitUpdateEffects<State>(
          effect: Update<State> | null,
          instance: any,
        ): void {
          while (effect !== null) {
            const callback = effect.callback;
            // 判断一下这个 effect 上面是否有 callback
            if (callback !== null) {
              effect.callback = null;
              // 如果有callback,我们执行callback
              callCallback(callback, instance);
            }
            effect = effect.nextEffect;
          }
        }
        // setState 中的 回调就是在这个时候执行的
        // 在这个时间点上,这个 update 对应的更新已经执行了,它已经反映到了我们的 state 和 props 上面
        // 在 setState 中的 回调才会执行
        // 在之前的 processUpdateQueue 方法里面,没有执行回调的过程的,如果有回调,回调就会把它放到对应的 update 里面
        function callCallback(callback, context) {
          invariant(
            typeof callback === 'function',
            'Invalid argument passed as callback. Expected a function. Instead ' +
              'received: %s',
            callback,
          );
          callback.call(context);
        }
        
    • 进入 commitMount
      // 先判断了一下是否要 autofocus 这个 HostComponent
      // 在之前 completeUnitOfWork 的时候,会判断过这个组件是否有 autofocus 这个属性的
      // 然后会给它加上一个 update 的 SideEffect
      // 而在这里,同样判断它是是否有 update 这个 SideEffect
      // 同时它只有在 current 等于 null 的一个情况下才会被调用 (限制条件在外部调用方)
      // 其实 这也就符合我们对于 autofocus 的一个认知
      // 在页面初次渲染的时候,它才会去自动获取需要被 autofocus 的节点 
      // 同样的对于react当中它的一个判断方式就非常的简单,就是通过current是否等于null来进行判断。
      // 如果有update,我们就执行这个方法来判断一下它是否是一个autofocus的组件。
      // 然后进行一个手动触发这个focus的过程
      export function commitMount(
        domElement: Instance,
        type: string,
        newProps: Props,
        internalInstanceHandle: Object,
      ): void {
        // Despite the naming that might imply otherwise, this method only
        // fires if there is an `Update` effect scheduled during mounting.
        // This happens if `finalizeInitialChildren` returns `true` (which it
        // does to implement the `autoFocus` attribute on the client). But
        // there are also other cases when this might happen (such as patching
        // up text content during hydration mismatch). So we'll check this again.
        if (shouldAutoFocusHostComponent(type, newProps)) {
          ((domElement: any):
            | HTMLButtonElement
            | HTMLInputElement
            | HTMLSelectElement
            | HTMLTextAreaElement).focus();
        }
      }
      
      function shouldAutoFocusHostComponent(type: string, props: Props): boolean {
        switch (type) {
          case 'button':
          case 'input':
          case 'select':
          case 'textarea':
            return !!props.autoFocus;
        }
        return false;
      }
      
  • 以上是对所有的具有 SideEffect 的节点在commit过程当中执行任务的一个过程,到这里,整个dom树其实也已经渲染上去了

  • commitAllLifeCycles 其实主要是调用不同组件的一个生命周期,以及对于 HostComponent,等组件的不同处理

  • 包括可能存在 autofocus 的处理过程,所以它相当于是在整个应用渲染完成之后的一个善后工作

  • 具体细节,写在上述代码的注释中

万字长文解密:SAP Fiori 首屏加载缓慢背后的真相 什么是一个健康理想的 Fiori 首次加载状态?FLP 首页不臃肿,用户默认看见的内容不多但足够用缓存作业按规则运行,冷启动不至于每次都从零开始应用首屏只读必要数据,UI5 资源经过 preload,视图异步加载OData 服务字段克制、分页合理、缓存分层清楚后台 CDS 与 HANA 只为当前屏幕做最必要的工作。只要这些标准同时满足,用户第一次打开 Fiori 页面的体感通常会从明显卡顿变成可接受甚至顺滑。 阅读详情

相关推荐

C/C++ 计算程序运行的时间

C/C++计算程序执行时间的方法,精度依次增加,推荐度也依次增加 1.#include <time.h> clock_t start, finish; double process_interval ; start=clock(); process(); //要计时的程序 finish=clock(); process_interval =(double)(finish-star...

stu_shanghui的博客 1020

Fix signatures do not match the previously installed version

报错信息FAILURE: Build failed with an exception.* What went wrong: Execution failed for task ':app:installDebug'. > com.android.builder.testing.api.DeviceException: com.android.ddmlib.InstallException: Fai

Wang的专栏 2万+

ESP32语音交互实战:离线唤醒与DeepSeek大模型集成

本文详细介绍了如何将ESP32-S3开发板与天问ASRPRO语音模块结合,实现离线语音唤醒并集成DeepSeek大模型的智能交互系统。通过串口通信与API调用,系统可处理本地指令及复杂语义请求,适用于低成本、高隐私保护的AIoT语音交互场景。

rust6ferris的博客 872

在react中 实现 base64的图片转换成formdata格式并实现上传功能

如果不想要服务端实现处理base64格式的图片的转换,那么在浏览器端来实现,部分属于伪代码,仅作为开发参考,请勿直接拷贝使用

Wang的专栏 8836

自回归分布滞后模型 (ARDL)及 Stata 具体操作步骤

例如,Bahmani-Oskooee 和 Brooks(1999)研究了汇率波动与贸易收支之间的关系,发现汇率的变动在长期和短期内对贸易收支的影响存在差异,ARDL 模型能够有效地捕捉这种复杂的关系。它结合了自回归(Autoregressive,AR)模型和分布滞后(Distributed Lag,DL)模型的特点,能够同时考察变量之间的短期和长期关系。假设我们收集了一段时间内的居民消费和可支配收入数据,通过对这些数据进行分析和估计,可以得到模型的参数估计值,从而揭示消费与收入之间的短期和长期关系。

a519573917的博客 6097

ESP32驱动Xbox Series X手柄的BLE协议实现

蓝牙低功耗(BLE)是嵌入式设备无线交互的核心技术,其GATT协议架构支持自定义服务与特征值通信,广泛应用于游戏外设、工业遥控等场景。Xbox Series X手柄采用非标准私有BLE协议,需深度解析输入报告(64字节)、输出控制(振动/LED)及固件兼容性约束。该方案依托ESP32平台与NimBLE 2.1.0+协议栈,解决MTU协商、PHY配置与HCI事件同步等关键问题,实现125Hz实时输入采集与毫秒级振动反馈。适用于机器人遥操作、ROS2终端、LVGL交互界面等工程实践,是私有BLE设备逆向集成的典

weixin_42610671的博客 711

快速解决gradle下载慢的问题的小技巧

在ionic run 或build 或clean命令的时候,如果没有下载过gradle, 需要重新下载一次,而通过CLI的方式下载很慢,即使科学上网后,下载还是存在一些问题。这里总结一下,快速的下载安装方式。 步骤 本地安装 http-server 包, 通过 $ npm i -g http-server 的方式安装到全局 在官网上下载自己的版本,目前自带的版本是 2.14.1,其他版本可能在执行过

Wang的专栏 6714

幸狐RV1106开发板实战:5分钟搞定Yolo8模型部署(附避坑指南)

本文详细介绍了在幸狐RV1106开发板上快速部署YOLOv8模型的实战流程。通过RKNN-Toolkit2工具链,将ONNX模型转换为RV1106 NPU专用的RKNN格式,并完成交叉编译与上板运行。文章重点分享了环境搭建、模型转换的关键步骤以及常见的避坑指南,帮助开发者高效实现边缘AI目标检测应用。

weixin_28677451的博客 916

React 实现 2D 画板功能

在移动端或者PC端我们来模拟画板的实现, 支持清除和导出功能,此处简单实现,仅作开发参考。 效果演示 主要代码演示 /* 此模块用于实现签名绘图功能 */ // 需要用到的变量定义 let clickX = new Array(); let clickY = new Array(); let clickDrag = new Array(); let paint; let point...

Wang的专栏 4325

OPC UA 服务端的模拟工具及客户端工具

详细介绍如何使用 Prosys OPC UA Simulation Server 作为 OPC UA 服务端的模拟工具来生成数据模型,并使用 Softing OPC UA Client 作为客户端工具,直观地查看和验证模拟生成的数据。

weixin_44462773的博客 9889

STM32H743实战(三)-- 时钟系统配置

本文详细讲解了STM32H743时钟系统的配置方法,重点解析了为何选择400MHz而非理论极限480MHz作为稳定运行的主频。通过STM32CubeIDE环境,手把手指导如何从外部晶振配置、电源电压设置到PLL锁相环参数调整,最终实现稳定可靠的400MHz系统时钟,并提供了代码验证与常见问题排查指南。

weixin_29164185的博客 369

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

对于在 beginWork 中的 context 操作,可以看上述判断成立的条件下的代码,即便有符合跳过更新的操作,依然 需要 push 和 pop 操作。如果我们可以跳出组件的更新,也就是代表着当前这个 classComponent,它的state它的props都应该是没有任何变化的。对于子组件来说,它的所有子树所获取到的context肯定是经过子组件,和上层的父组件合并的 context 了, 也就是。所以,先 push 一个老的值进去再说, 然后到后面,如果发现这个组件它是要更新的,就调用这个。

Wang的专栏 2803

RK+linux教程:RK3588 RGA硬件加速在YOLOv5图像预处理中的深度应用教程

摘要: 本教程深入解析了RK3588芯片的RGA硬件加速器在YOLOv5图像预处理中的应用。通过专用硬件设计,RGA支持图像缩放、边界填充等核心操作,结合零拷贝技术显著提升处理效率。重点分析了LetterBox算法的RGA实现,包括参数计算、边界填充和性能优化,并与传统CPU处理对比,展示了RGA在高分辨率图像处理中的优势。教程还提供了统一的预处理接口设计,便于在OpenCV与RGA方案间灵活切换,为RK3588平台的深度学习部署提供实用优化方案。

LXY_LOVE36的博客 977

Fix babel-preset-react-native TransformError

错误环境新版本存在不兼容,在运行 react-native run-android 的时候,发生的错误分析: babel-preset-react-native version : @3.0.0 $ react-native -v :react-native-cli: 2.0.1 react-native: 0.47.1$node -v : v7.8.0 $ npm -v :4.4.4 解决方案

Wang的专栏 2800

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

React18原理: 再聊Fiber架构下的时间分片

react的任务可以被打断,其实就是基于时间分片的,人眼最高能识别的帧数不超过30帧,电影的帧数差不多是在24,浏览器的帧率一般来说是60帧,也就是每秒60个画面, 平均一个画面大概是16.5毫秒左右,浏览器正常的工作流程是运算渲染,运算,渲染运算渲染,在浏览器里面一个运算,加上一个渲染就是一帧

Wang的专栏 2796

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

在react项目中修改webpack中本地服务器架设的目录

一个产品的上线往往会有很多的问题,现在就出现一个需求,我们是在服务器下的某个目录进行发布,而不是根服务器,服务端不想为一个项目配置ip地址,而在react项目中,默认是走的根路径,现在我们就开始修改一下它。 前提说明 如果我们需要修改手动配置webpack, 那么根据现在的版本, 我们只能执行 npm run eject, 之后就可以着手修改了。 webpack中与需求相关的...

Wang的专栏 2397

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

React18源码: React调度中的3种优先级类型和Lane的位运算

可以看得出来lane&-lane的结果是SyncLane,所以通过lane&-lane就能分离出最高优先级的任务。即A(cpu)>B(IO)>C(cpu).此时的需求需要将任务B从group中分离出来,先处理cpu任务A和C。在新版本的React中,还有一个新特性,就是render阶段可能被中断,在这个期间会产生一个更高优先级的任务。如上就是通过 lanes & -lanes 分离出最高优先级的任务的,我们来看一下具体的流程。也即是说lane的代表的数值越小,此次更新的优先级就越大。

Wang的专栏 2394

React18原理: 核心包结构与两大工作循环

react中的工作循环,这是它的一个最顶层的一个流程图,在这张图里面,有两个核心的大循环,第一大循环是 react-reconciler 提供的,它的核心是构建fiber树,生成任务,第二大循环是 scheduler 提供的, 它的核心是任务调度(处理任务的优先级),react的原理实际上就是两大工作循环

Wang的专栏 2356

React18原理: 生命周期中特别注意事项

生命周期就是一个组件从诞生到销毁的全过程(包含错误捕获,这里暂且不聊这个)react 在组件的生命周期中注册了一系列的钩子函数支持开发者在其中嵌入代码,并在适当的时机运行生命周期本质上就是组件中的钩子函数,主要有三个主要的钩子挂载更新卸载。

Wang的专栏 2244

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

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

Wang的专栏 2140

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

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

Wang的专栏 2133

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

各种不同类型组件的一个更新过程对应的是在执行 `performUnitOfWork` 里面 `beginWork` 阶段,它是去向下遍历一棵 fiber 树的一侧的子节点,然后遍历到叶子节点为止,以及 return 自己 child 的这种方式

Wang的专栏 2088

React18原理: 渲染与更新时的重点关注事项

react 在渲染过程中要做很多事情,所以不可能直接通过初始元素直接渲染还需要一个东西,就是虚拟节点,暂不涉及React Fiber的概念,将vDom树和Fiber 树统称为虚拟节点有了初始元素后,React 就会根据初始元素和其他可以生成虚拟节点的东西生成虚拟节点React一定是通过虚拟节点来进行渲染的对于首次挂载阶段需要了解React的渲染流程通过书写的初始元素和一些其他可以生成虚拟节点的东西来生成虚拟节点然后针对不同的节点类型去做不同的事情,最终将真实DOM挂载到页面上。

Wang的专栏 2069

21st.dev 上手教程:12000+ React 组件库怎么用,6 步从挑样式到接进 Cursor

21st.dev 收录 12000+ 个 React + Tailwind 组件、297 套整站模板与 979 套主题。本文是手把手流程版:按页面用途找组件、用复制或 shadcn CLI 落地、接入 MCP 让 Cursor 自己取代码、用整站模板开局,附 10 张真实组件截图和 4 个常见坑。

懿轩的技术小窝 233

成为全栈·Vue 管理后台篇·Naive UI 主题对齐:React 后台配色与明暗模式

本文根据 React 管理后台的蓝紫主色与浅/深色语义令牌,分析 Vue 后台如何用 CSS custom properties、Naive UI `NConfigProvider`、theme overrides、Pinia UI store 和系统媒体查询完成主题对齐。文章说明 CSS class 与 Naive UI darkTheme 必须同步,Markdown 编辑器/预览需要单独接入 resolvedTheme,并通过主题/侧栏持久化区分非敏感偏好与认证凭证。

FungLeo's Blog 274

手搓 AI Agent 02:让模型第一次“动手“——Agent Loop 与 ReAct

本系列第2篇实现Agent核心循环——ReAct模式,让模型从“被动回答”变为“主动执行”。通过LLMClient工具调用能力,构建think → act → observe闭环,首次实现模型自主调用计算器、读取结果并继续推理。代码支持安全算术、步数限制与错误隔离,升级终端REPL为可观察的智能体交互界面。每步操作清晰可见,为后续多工具、规划与协作打下基础。

快乐来自程序里 131
上一篇: React16源码: React中commitAllHostEffects内部的commitDeletion的源码实现
下一篇: React16源码: React中context-stack的源码实现
Wang's Blog
博客等级 码龄12年 7438粉丝 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、付费专栏及课程。

余额充值