React18引入一个新的API,ReactDOM.createRoot,原先的 ReactDOM.render 会被标记为弃用

Warning: ReactDOM.render is no longer supported in React 18. Use createRoot instead. Until you switch to the new API, your app will behave as if it's running React 17. Learn more: https://reactjs.org/link/switch-to-createroot
console.<computed> @ index.js:1

ReactDOM.createRoot 会开启并发特性(concurrent features),两者的区别如下

初始化阶段

旧的写法,需要多次传 container 这个变量

const container = document.getElementById('app');
// 首次渲染
ReactDOM.render(<App tab="home" />, container);
// 更新的时候,react会再次访问DOM元素
ReactDOM.render(<App tab="profile" />, container);

新的写法,在 crateRoot 的时候会返回 root 实例,每次只需要调用 render 方法即可

const container = document.getElementById('app');
// 创建root
const root = ReactDOM.createRoot(container);
// 首次渲染到root
root.render(<App tab="home" />);
// 更新的时候,不需要再次访问container元素
root.render(<App tab="profile" />);

渲染回调

使用旧的api,在第三个参数里就可以使用该回调

ReactDOM.render(<App theme="dark" />, container, function () {
  console.log('渲染完成')
});

使用新的api,移除了第三个回调参数,可以通过 requestIdleCallback  ,setTimeout 或者 ref callback 来实现

function App({ callback }) {
  // 首次渲染回调
  return (
    <div ref={callback}>
      <h1>Hello World</h1>
    </div>
  );
}
const rootElement = document.getElementById("root");
const root = ReactDOM.createRoot(rootElement);
root.render(<App callback={() => console.log("渲染完成")} />);

hydrate api

hydrate 使用在ssr,用于在 ReactDOMServer 渲染的容器中对 HTML 的内容进行 hydrate 操作,React 会尝试在已有标记上绑定事件监听器

旧的写法

const container = document.getElementById('root');
ReactDOM.hydrate(<App theme="dark" />, container);

新的写法,参数位置对调了

const container = document.getElementById('root');
// Create and render a root with hydration.
const root = ReactDOM.hydrateRoot(container, <App theme="dark" />);

封面来源:https://dribbble.com/shots/16721630-Delivery-truck?utm_source=Clipboard_Shot&utm_campaign=One_Pixel_Lefts&utm_content=Delivery%20truck&utm_medium=Social_Share&utm_source=Clipboard_Shot&utm_campaign=One_Pixel_Lefts&utm_content=Delivery%20truck&utm_medium=Social_Share