生态与帮助 · React 19
适配
React 19 适配指南
Semi Design 现已支持 React 19。由于 React 19 引入了一些底层 API 的变更,使用时需要进行简单的适配。
React 19 的特殊之处
React 19 移除了两个 Semi 组件库依赖的 API:
1. ReactDOM.render 被移除
React 19 移除了传统的
ReactDOM.render API,改为使用 createRoot。Semi 的以下组件依赖此 API 来动态挂载内容:Modal.info()/Modal.success()/Modal.error()/Modal.warning()/Modal.confirm()Toast.info()/Toast.success()/Toast.error()/Toast.warning()Notification.info()/Notification.success()/Notification.error()/Notification.warning()
2. ReactDOM.findDOMNode 被移除
React 19 移除了
ReactDOM.findDOMNode API,该 API 用于从类组件实例获取对应的 DOM 节点。Semi 的以下组件受影响:Tooltip及所有基于它的弹出层组件(Popover、PopConfirm、Dropdown等)
为什么需要 adapter?
由于 Semi 需要同时支持 React 16/17/18/19,而 React 19 的
createRoot 位于 react-dom/client 子路径中,直接在库内部导入会导致低版本 React 报错。因此我们采用 adapter 模式,让 React 19 用户显式注入所需的 API。快速开始
安装
无论你使用的是 React 16、17、18 还是 19,都使用同一个包:
React 19 用户(重要)
如果你的项目使用 React 19,需要在应用入口文件的最顶部导入 adapter:
然后正常使用 Semi 组件:
React 16/17/18 用户
对于 React 16、17、18 项目,无需任何额外配置,直接使用即可:
注意事项
Tooltip 与类组件的限制
由于 React 19 移除了
ReactDOM.findDOMNode,当 Tooltip(及基于它的 Popover、PopConfirm、Dropdown 等)的 children 是类组件时,可能无法正确获取 DOM 节点进行定位。受影响的场景:
解决方案:用 DOM 元素包裹类组件
不受影响的场景:
- 函数组件配合
forwardRef正确转发 ref 的情况 - 原生 DOM 元素(如
<span>、<div>、<button>等)
错误提示
如果你在 React 19 中忘记导入 adapter,控制台会显示以下错误:
看到此错误时,请在入口文件顶部添加:
常见问题
Q: 在 React 18 中导入 adapter 会有问题吗?
A: 不会。在 React 18 中,Semi 会自动检测并使用内置的
createRoot,adapter 的导入不会产生副作用。Q: adapter 做了什么?
A: adapter 只做一件事:将 React 19 的
createRoot 函数注入到 Semi 内部,使 Modal、Toast、Notification 等组件能够正常工作。代码非常简单:Q: 为什么 adapter 必须在最顶部导入?
A: 因为 adapter 需要在任何 Semi 组件渲染之前完成
createRoot 的注入。如果在组件已经开始渲染后才导入,可能会导致首次渲染失败。Q: 我之前使用的是
@douyinfe/semi-ui-19,如何迁移?A:
- 卸载
@douyinfe/semi-ui-19 - 安装
@douyinfe/semi-ui(如果还没安装) - 将所有
from '@douyinfe/semi-ui-19'改为from '@douyinfe/semi-ui' - 在入口文件顶部添加
import '@douyinfe/semi-ui/react19-adapter'
技术细节
版本兼容性矩阵
| React 版本 | 是否需要 adapter | ReactDOM.render | createRoot |
|---|---|---|---|
| 16.x | 否 | ✅ 使用 | ❌ 不存在 |
| 17.x | 否 | ✅ 使用 | ❌ 不存在 |
| 18.x | 否 | ⚠️ 已废弃 | ✅ 自动使用 |
| 19.x | 是 | ❌ 已移除 | ✅ 需注入 |
adapter 的工作原理
- React 16/17:使用传统的
ReactDOM.render和ReactDOM.unmountComponentAtNode - React 18:自动检测并使用
react-dom导出的createRoot - React 19:
createRoot不再从react-dom直接导出,需要从react-dom/client导入,通过 adapter 注入