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

相关推荐
阿桂有点桂4 小时前
React使用笔记(持续更新中)
前端·javascript·react.js·react
im_AMBER5 小时前
React 15
前端·javascript·笔记·学习·react.js·前端框架
疯狂踩坑人12 小时前
结合400行mini-react代码,图文解说React原理
前端·react.js·面试
devincob1 天前
js原生、vue导出、react导出、axios ( post请求方式)跨平台导出下载四种方式的demo
javascript·vue.js·react.js
编程社区管理员1 天前
React 发送短信验证码和验证码校验功能组件
前端·javascript·react.js
葡萄城技术团队1 天前
迎接下一代 React 框架:Next.js 16 核心能力解读
javascript·spring·react.js
全马必破三1 天前
React“组件即函数”
前端·javascript·react.js
三思而后行,慎承诺1 天前
React 底层原理
前端·react.js·前端框架
im_AMBER1 天前
React 16
前端·笔记·学习·react.js·前端框架
这儿有一堆花1 天前
告别 Class 组件:拥抱 React Hooks 带来的函数式新范式
前端·javascript·react.js