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... 希望对大家有用

相关推荐
摸鱼仙人~1 小时前
React: hook相当于函数吗?
前端·javascript·react.js
百锦再1 小时前
React编程高级主题:错误处理(Error Handling)
前端·javascript·react.js·前端框架·vue·web·angular
FanetheDivine3 小时前
solid: react导演剪辑终极扑街版
前端·react.js
腾讯TNTWeb前端团队14 小时前
helux v5 发布了,像pinia一样优雅地管理你的react状态吧
前端·javascript·react.js
市民中心的蟋蟀1 天前
第五章 使用Context和订阅来共享组件状态
前端·javascript·react.js
谦谦橘子1 天前
服务端渲染原理解析
前端·javascript·react.js
安分小尧1 天前
[特殊字符] 使用 Handsontable 构建一个支持 Excel 公式计算的动态表格
前端·javascript·react.js·typescript·excel
ElasticPDF-新国产PDF编辑器1 天前
React 项目 PDF 批注插件库在线版 API 示例教程
react.js·pdf·json
帅帅哥的兜兜1 天前
react中hooks使用
前端·javascript·react.js