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

相关推荐
小矮马2 小时前
React-组件和props
前端·javascript·react.js
懒羊羊我小弟2 小时前
React Router v7 从入门到精通指南
前端·react.js·前端框架
gaog2zh2 小时前
0803分页_加载更多-网络ajax请求2-react-仿低代码平台项目
react.js·ajax·分页·加载更多
Mars狐狸3 小时前
AI项目改用服务端组件实现对话?包体积减小50%!
前端·react.js
吃面必吃蒜4 小时前
从 Vue 到 React:React 合成事件
javascript·vue.js·react.js
举个栗子dhy4 小时前
【血缘关系图下钻节点,节点展开收起功能,递归和迭代问题处理】
javascript·react.js
Aiolimp5 小时前
React中CSS使用方法
前端·react.js
Moment5 小时前
受控组件和非受控组件的区别?别再傻傻分不清了 😁😁😁
前端·javascript·react.js
数据智能老司机6 小时前
React关键概念——处理事件和状态
react.js·前端框架·前端工程化
数据智能老司机8 小时前
React关键概念——理解React组件与JSX
react native·react.js·前端框架