用途
DOM 组件允许 Web 代码在原生平台上原封不动地运行于 WebView 中,同时在 Web 平台上按原样渲染。它适用于以下场景:需要使用仅支持 Web 的库(如图表库 recharts、chart.js,语法高亮库,富文本编辑器,或任何依赖 DOM API 的库);将现有 React Web 组件迁移到原生端而无需重写;实现 React Native 中不可用的复杂 HTML/CSS 布局;嵌入需要浏览器上下文的 iframe 或外部内容;使用原生不支持的 Canvas 或 WebGL 等 Web 图形 API。
主要能力
- 在原生 WebView 中运行 Web 代码,在 Web 平台直接渲染。
- 支持任意 Web 库,包括 recharts、react-syntax-highlighter 等。
- 通过 dom prop 配置 WebView 行为,如禁用滚动、控制安全区域、手动设置尺寸等。
- 可将原生异步函数作为 props 传入,向 WebView 暴露原生功能。
- 支持在 DOM 组件内使用 CSS 导入、内联样式或 CSS-in-JS。
- 支持 expo-router 的 Link 组件和 router API。
- 提供 IS_DOM 用于检测代码是否运行在 DOM 组件中。
- 支持资源加载,推荐使用 require 而非 public 目录。
使用方式
创建文件并在顶部添加 'use dom'; 指令,每个文件只能有一个默认导出,不能内联定义或与原生组件混合。props 仅支持可序列化类型(字符串、数字、布尔值、数组、普通对象)。每个 DOM 组件都会接收一个特殊的 dom prop,需在 props 类型中声明为 import("expo/dom").DOMProps。CSS 导入必须放在 DOM 组件文件内,因为其运行在隔离上下文中。在原生组件中像普通组件一样导入并使用 DOM 组件。
部分 expo-router 钩子(useLocalSearchParams、useGlobalSearchParams、usePathname、useSegments、useRootNavigation、useRootNavigationState)无法直接在 DOM 组件中使用,需在原生父组件中读取后作为 props 传入。
适用场景
适合需要在 Expo 应用中集成 Web 专属库、渐进式迁移 Web 代码、使用复杂 CSS 布局或嵌入浏览器上下文内容的开发者。
限制
原生性能关键场景、简单 UI、需要深度原生集成、以及 _layout 布局路由文件均不适合使用 DOM 组件。WebView 有独立的 JavaScript 上下文,无法与原生直接共享状态。大型 DOM 组件可能影响性能。Web 平台会忽略 dom prop。各平台渲染可能存在细微差异,建议在所有平台测试。