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" />);