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

相关推荐
摘星编程9 小时前
React Native鸿蒙:BiometricAuth指纹解锁实现
react native·react.js·harmonyos
摘星编程10 小时前
用React Native开发OpenHarmony应用:NFC读取标签数据
javascript·react native·react.js
哈哈你是真的厉害11 小时前
小白基础入门 React Native 鸿蒙跨平台开发:实现一个简单的文件路径处理工具
react native·react.js·harmonyos
哈哈你是真的厉害12 小时前
小白基础入门 React Native 鸿蒙跨平台开发:实现一个简单的个人所得税计算器
react native·react.js·harmonyos
哈哈你是真的厉害13 小时前
小白基础入门 React Native 鸿蒙跨平台开发:二维码生成工具(通过生成网址生成)
react native·react.js·harmonyos
摘星编程16 小时前
OpenHarmony环境下React Native:Sensors摇一摇换图
javascript·react native·react.js
壹号机长17 小时前
canvas烟花特效各种前端框架都可以使用H5,vue,react,
vue.js·react.js·前端框架
摘星编程17 小时前
React Native鸿蒙版:Bluetooth扫描蓝牙设备
react native·react.js·harmonyos
打小就很皮...18 小时前
React 合同审查组件:文档结构树渲染及定位详解
react.js·markdown·tree
Marshmallowc18 小时前
React性能优化:useState初始值为什么要用箭头函数?深度解析Lazy Initialization与Fiber机制
前端·react.js·性能优化·前端框架·react hooks