outline: [2, 3]
React 18 ReactDOM.createRoot 替代 render()
问题描述
升级到 React 18 后,许多开发者会遇到以下警告信息:
WARNING
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
这个警告出现在使用 create-react-app
创建新项目时:
npx create-react-app my-app
问题原因
React 18 在 2022 年 3 月 29 日发布,引入了新的根API(root API)。之前的 ReactDOM.render()
方法已被弃用,虽然目前仍能在兼容模式下运行,但未来可能会被完全移除。
解决方案
方法一:基本迁移方案
将原来的 ReactDOM.render()
替换为新的 createRoot
API:
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
reportWebVitals();
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
reportWebVitals();
方法二:简化导入方式
可以直接从 react-dom/client
导入 createRoot
:
import { createRoot } from 'react-dom/client';
import App from './App';
const root = createRoot(document.getElementById('root'));
root.render(<App />);
方法三:TypeScript 版本
对于 TypeScript 项目,需要添加类型断言:
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
);
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
reportWebVitals();
方法四:使用 React Router 的项目
如果你的应用使用了 React Router,更新方式如下:
import { createRoot } from "react-dom/client";
import { BrowserRouter } from "react-router-dom";
import App from "./App";
const container = document.getElementById("root");
const root = createRoot(container);
root.render(
<BrowserRouter>
<App />
</BrowserRouter>
);
代码对比
import React from 'react';
import ReactDOM from 'react-dom';
ReactDOM.render(<App />, document.getElementById('root'));
import { createRoot } from 'react-dom/client';
createRoot(document.getElementById('root')).render(<App />);
注意事项
WARNING
虽然 React 18 目前仍然支持 ReactDOM.render()
的兼容模式,但建议尽快迁移到新的 API,因为:
- 旧 API 已被标记为 deprecated
- 新 API 启用了 React 18 的所有新特性
- 未来版本可能会完全移除对旧 API 的支持
为什么需要这个更改?
React 18 引入的新根API提供了更好的性能和改进的并发特性(Concurrent Features)。新的 createRoot
API 为以下功能奠定了基础:
- 自动批处理(Automatic Batching)
- 过渡更新(Transitions)
- Suspense 服务端渲染
扩展阅读
现在你已经了解了如何在 React 18 中正确初始化应用,赶快更新你的项目代码吧!