ReactDOM.createRoot 与 ReactDOM.render差异

ReactDOM.createRoot 是 React 18 引入的新根 API,与 ReactDOM.render 有何不同?让我们来详细了解一下吧。

👉 ReactDOM.render

每当我们想要显式渲染时,都必须将容器传递给 render 函数。

ini 复制代码
const container = document.querySelector('#root');

// 初始渲染:容器需要显式访问
ReactDOM.render(<App text="Hello" />, container);

// 后续渲染:容器需要显式访问
ReactDOM.render(<App text="Hello world!" />, container);

👉 ReactDOM.render 接受什么参数?

render 函数接受三个参数:

  • 要渲染的 React 元素
  • 要在其中进行渲染的 DOM 元素
  • 在渲染完成后要执行的函数

并返回相同的容器,但其中包含了已渲染的组件。

php 复制代码
/**
* @param element - 要渲染的 React 元素
* @param container - 要进行渲染的 DOM 元素
* @param callback - 在渲染完成后要执行的函数
* @return container - 包含已渲染组件的容器
*/
function render(element, container, callback) {
  // ...
}

👉 ReactDOM.render 在内部是如何工作的?

ReactDOM.render 执行了一些验证检查:

  • 它会验证容器是否是一个合适的节点。
  • 它还会验证容器是否之前没有传递给 createRoot

然后,它将接收到的所有参数传递给 legacyRenderSubtreeIntoContainer

javascript 复制代码
// 简化的结构
function render(element, container, callback) {
  if (isValidContainer(element)) {
    throw Error('目标容器不是 DOM 元素');
  }

  if (isContainerMarkedAsRoot(container) && container._reactRootContainer === undefined) {
    // 不会抛出错误,但会将其记录到控制台
    error('容器之前已传递给 ReactDOM.createRoot()');
  }

  return legacyRenderSubtreeIntoContainer(null, element, container, false, callback);
}

👉 ReactDOM.createRoot

ReactDOM.createRoot解决了每次想要显式渲染时都需要传递容器的问题。

ini 复制代码
// 首先,我们创建一个根
const root = ReactDOM.createRoot(document.querySelector('#root'));

// 初始渲染:容器被隐式访问。
root.render(<App name="Hello" />);

// 后续渲染:容器被隐式访问。
root.render(<App name="Hello world!" />);

👉 ReactDOM.createRoot 接受什么参数?

createRoot 函数仅接受一个必需的参数 ------ 用于渲染的 DOM 元素。 它返回 RootType,其中包含 renderunmount 方法。

注:createRoot 还接受第二个 RootOptions 参数,但我们将在将来进行更详细的讨论。

php 复制代码
/**
* @param container - 用于渲染的 DOM 元素
* @param options - 相关的选项
* @return RootType - 根实例
*/
function createRoot(container, options) {
  // ...
}

👉 ReactDOM.createRoot 在内部是如何工作的?

在 render 函数之上,createRoot

  • 检查容器是否不是 body 元素。
  • 提供了更详细的警告。

然后,createRoot 实例化一个新的 ReactDOMRoot 对象并返回它。完全没有 legacyRenderSubtreeIntoContainer

javascript 复制代码
// 简化的结构
function createRoot(container, options) {
  if (isValidContainer(element)) {
    throw Error('目标容器不是 DOM 元素');
  }

  if (container.nodeType === 1 && container.tagName.toUpperCase() === 'BODY') {
    console.error('不推荐直接使用 document.body 创建根');
  }

  if (isContainerMarkedAsRoot(container) {
    if (container._reactRootContainer) {
      console.error('容器之前已传递给 ReactDOM.render()')
    } else {
      console.error('容器之前已传递给 createRoot()');
    }
  }

  return new ReactDOMRoot(container, options);
}

翻译自dev.to/fromaline/r... 希望对大家有用

相关推荐
AI周红伟2 小时前
长鑫科技存储之王:存储三强对比:三星、SK海力士 vs 长鑫科技
数据库·人工智能·科技·react.js·架构·langchain
右耳朵猫AI3 小时前
React技术周刊 2026年第20周
前端·react.js·前端框架
光影少年3 小时前
react全局状态、局部状态、服务端状态如何选型
前端·react.js·掘金·金石计划
Java陈序员3 小时前
主流数据库通吃!一款开源实用的数据库备份管理工具!
react.js·postgresql·go
孟陬4 小时前
首次上榜新项目 HyperFrames(22k Star):HTML → MP4 一句话生成视频
react.js·node.js·html
喵个咪1 天前
Headless 后端实践:基于Go的企业级多栈管理系统脚手架
前端·vue.js·react.js
代码N年归来仍是新手村成员1 天前
【AWS】Lambda 初识与服务部署
javascript·react.js·ai·node.js·云计算·ai编程·aws
大雷神1 天前
HarmonyOS APP<玩转React>开源教程三十一:示例项目下载功能
react.js·开源·harmonyos
大鱼前端1 天前
Veaury:让Vue和React组件在同一应用中共存的神器
前端·vue.js·react.js
五月君_1 天前
继 React、Vue 之后,Three.js 也有 Skills 了!AI 写 3D 终于不“晕”了
javascript·vue.js·人工智能·react.js·3d