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-createrootconsole.<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');// 创建rootconst root = ReactDOM.createRoot(container);// 首次渲染到rootroot.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" />);