React中updateContainerImpl方法更新容器源码解析

 更新时间:2026年01月26日 14:11:58   作者:Jinuss  
updateContainerImpl方法是React中更新容器的核心方法,负责创建和调度更新,通过createUpdate方法创建更新对象,并通过enqueueUpdate方法将其加入Fiber节点的更新队列,本文介绍React中updateContainerImpl方法更新容器源码分析,感兴趣的朋友一起看看吧

概览

ReactDOMRootrenderunmount方法中均调用了updateContainerImpl方法,该方法是React中更新容器的核心方法,负责创建和调度更新。

源码分析

updateContainerImpl

updateContainerImpl方法源码实现如下:

function updateContainerImpl(
  rootFiber, //根Fiber节点
  lane, // 更新优先级
  element, //要渲染的React元素
  container, // Fiber根节点容器
  parentComponent, // 父组件
  callback // 更新完成后的回调函数
) {
  // 获取子树的上下文,会返回一个空对象
  parentComponent = getContextForSubtree(parentComponent);
  // 若Fiber根节点容器上下文为空,则设置其为获取到的上下文(空对象);否则设置待处理的上下文为空对象
  null === container.context
    ? (container.context = parentComponent)
    : (container.pendingContext = parentComponent);
  // 根据优先级车道创键更新对象  
  container = createUpdate(lane);
  // 将要渲染的React元素作为更新对像的载荷
  container.payload = { element: element };

  // 若回调未定义,则设为null,否则保留原值
  callback = void 0 === callback ? null : callback;
  // 若回调不为null,则将其设为更新对象的callback属性值
  null !== callback && (container.callback = callback);
  
  // 将更新对象添加到Fiber节点的更新队列,并获取FiberRoot
  element = enqueueUpdate(rootFiber, container, lane);

  // 判断 若返回的更新对象不为null,则调度更新
  null !== element &&
    (scheduleUpdateOnFiber(element, rootFiber, lane),
    entangleTransitions(element, rootFiber, lane));
}

createUpdate

createUpdate接受一个参数车道优先级(lane),返回一个更新对象,其对象类型为UpdateUpdate会被放入更新队列中等待调度执行,其优先级为参数lanetagUpdateState:0,其实现如下:

function createUpdate(lane){
  return {
    lane: lane,  // 更新优先级
    tag: UpdateState, // 其值为1 ,表示更新类型
    payload: null, // 更新载荷
    callback: null, // 回调函数
    next: null // 指向下一个更新
  }
}

enqueueUpdate

enqueueUpdate方法用于将更新对象加入Fiber节点的更新队列,其源码实现如下:

function enqueueUpdate(fiber, update, lane) {
  // 获取Fiber节点上的更新队列updateQueue
  var updateQueue = fiber.updateQueue;
  // 若更新队列为空,则返回null,此时Fiber节点已被卸载
  if (null === updateQueue) return null;
  // 获取共享队列
  updateQueue = updateQueue.shared;

  // 检查是否是渲染更新阶段
  if (0 !== (executionContext & 2)) {
    // 获取共享队列的最后一个节点
    var pending = updateQueue.pending;
    // 判断最后一个节点是否为空
    null === pending
      ? (update.next = update) // 将更新对象update的next指向自身
      : ((update.next = pending.next), (pending.next = update)); //否则将更新对象的next指向最后一个节点的next,并且将最后一个节点的next指向更新对象,即将更新对象插入到环形链表的末尾
    // 更新pending指针  
    updateQueue.pending = update;
    // 从Fiber节点中获取FiberRoot
    update = getRootForUpdatedFiber(fiber);
    // 标记fiber节点中的优先级
    markUpdateLaneFromFiberToRoot(fiber, null, lane);
    // 最后返回FiberRoot
    return update;
  }
  // 若不是渲染更新阶段,则依次执行enqueueUpdate$1,getRootForUpdatedFiber,最后返回getRootForUpdatedFiber的结果FiberRoot
  // 调用enqueueUpdate$1方法就是将相关参数放到并发队列concurrentQueues中
  enqueueUpdate$1(fiber, updateQueue, update, lane);
  return getRootForUpdatedFiber(fiber);
}

getRootForUpdatedFiber

Fiber节点的return始终是指向父节点,因此通过不断追溯return可以找到根节点;

function getRootForUpdatedFiber(sourceFiber) {
  // 判断某计数器,暂且不提
  if (50 < nestedUpdateCount)
    throw (
      ((nestedUpdateCount = 0),
      (rootWithNestedUpdates = null),
      Error(formatProdErrorMessage(185)))
    );
  for (var parent = sourceFiber.return; null !== parent; )
    (sourceFiber = parent), (parent = sourceFiber.return);
  
  // 判断当前Fiber节点的根节点类型是否为HostRoot,若是,则返回其DOM元素,否则返回null
  return 3 === sourceFiber.tag ? sourceFiber.stateNode : null;
}

scheduleUpdateOnFiber

调用enqueueUpdate方法更新相关队列后,会拿到FiberRoot,若FiberRoot不为null,则调用scheduleUpdateOnFiber进行调度更新。

entangleTransitions

entangleTranslations方法用于纠缠过渡更新,主要有3个作用:

  1. 将当前更新与正在进行的过渡更新纠缠
  2. 确保过渡更新的正确顺序
  3. 处理并发模式下的更新冲突

到此这篇关于React中updateContainerImpl方法更新容器源码解析的文章就介绍到这了,更多相关React updateContainerImpl更新容器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • react-redux的connect用法详解

    react-redux的connect用法详解

    react-redux是react官方推出的redux绑定库,React-Redux 将所有组件分成两大类一个是UI组件和容器组件,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2023-01-01
  • 用React实现一个完整的TodoList的示例代码

    用React实现一个完整的TodoList的示例代码

    本篇文章主要介绍了用React实现一个完整的TodoList的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-10-10
  • React中memo useCallback useMemo方法作用及使用场景

    React中memo useCallback useMemo方法作用及使用场景

    这篇文章主要为大家介绍了React中三个hooks方法memo useCallback useMemo的作用及使用场景示例,有需要的朋友可以借鉴参考下,希望能够有所帮助
    2023-03-03
  • React中使用collections时key的重要性详解

    React中使用collections时key的重要性详解

    这篇文章主要给大家介绍了关于在React.js中使用collections时key的重要性,注意:一定不能不能忘了key,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴,下面跟着小编来一起学习学习吧。
    2017-08-08
  • useCallback和useMemo的正确用法详解

    useCallback和useMemo的正确用法详解

    这篇文章主要为大家介绍了useCallback和useMemo的正确用法详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-01-01
  • React实现过渡效果更新时间展示功能

    React实现过渡效果更新时间展示功能

    创建一个组件,实时展示时分秒,并且动态更新数据,这篇文章主要介绍了React实现过渡效果更新时间展示功能,需要的朋友可以参考下
    2024-07-07
  • react创建项目启动报错的完美解决方法

    react创建项目启动报错的完美解决方法

    这篇文章主要介绍了react创建项目启动报错的完美解决方法,全称为Node Package Manager,是随同NodeJS一起安装的包管理工具,本文通过实例代码给大家介绍的非常详细,需要的朋友可以参考下
    2022-08-08
  • React中setState使用原理解析

    React中setState使用原理解析

    这篇文章主要介绍了React中的setState使用细节和原理解析,主要包括使用setstate的原因及基本用法,本文通过实例代码给大家详细讲解,需要的朋友可以参考下
    2022-10-10
  • 详解antd+react项目迁移vite的解决方案

    详解antd+react项目迁移vite的解决方案

    这篇文章主要介绍了详解antd+react项目迁移vite的解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04
  • react+react-beautiful-dnd实现代办事项思路详解

    react+react-beautiful-dnd实现代办事项思路详解

    这篇文章主要介绍了react+react-beautiful-dnd实现代办事项,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-06-06

最新评论