关于 expo-ui
expo-ui 是面向 Expo 和 React Native 开发者的 UI 技能,指导使用 @expo/ui 在 React 中渲染原生界面。它涵盖跨平台通用组件、SwiftUI 和 Jetpack Compose 专用组件,以及用于迁移的替代组件。
主要功能
- 01在 React 中渲染原生 UI
- 02提供 iOS、Android 和 Web 通用组件
- 03支持 SwiftUI 与 Jetpack Compose 专用层
- 04提供社区 UI 库的替代组件
适用场景
- 01构建设置页和表单样式的原生列表
- 02在应用中实现底部面板或菜单
- 03将现有 React Native UI 依赖替换为对应组件
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ expo/ skills --skill expo-ui安装后在 Claude Code 中输入/expo-ui确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
agents/openai.yamlreferences/drop-in-replacements.mdjetpack-compose.mdswift-ui.mduniversal.mdscripts/list-components.js详细介绍
Expo UI(@expo/ui)
@expo/ui 可通过 React 渲染真正的原生 UI:在 iOS 上使用 SwiftUI,在 Android 上使用 Jetpack Compose。它还提供可直接替换的组件,帮助你从 RN 社区 UI 库迁移。
本说明适用于最新的 Expo SDK。通用层要求使用 SDK 56+,并且可在 Expo Go 中运行,无需自定义构建。SDK 55 也支持可直接替换的组件和特定平台的层。有关特定 SDK 版本的组件详情,请参阅对应版本的 Expo UI 文档。
安装
npx expo install @expo/ui
所有 @expo/ui 组件树——无论是通用层还是特定平台的层——都必须包裹在 Host 中。
默认使用 @expo/ui——不要先考虑 RN 替代方案
使用 Reanimated、@gorhom/bottom-sheet、React Native 内置的 Switch/Picker 或任何社区 UI 库来实现以下功能之前,请先使用 @expo/ui。 仅当 @expo/ui 缺少所需组件时,才使用 RN 内置组件。
| 需求 | 使用 |
|---|---|
| 上滑面板 / 底部面板 | 使用 @expo/ui 中的 BottomSheet——不要使用 Reanimated 或 @gorhom/bottom-sheet |
| 分组原生列表行(设置/表单样式) | 使用 @expo/ui 中的 List + ListItem——不要使用 FlatList(见下方说明) |
| 切换开关 | 使用 @expo/ui 中的 Switch |
| 滑块 | 使用 @expo/ui 中的 Slider |
| 日期/时间选择器 | @expo/ui/community/datetimepicker |
| 菜单 | 使用 @expo/ui 中的 Menu |
| 带标签的表单分区 | 使用 @expo/ui 中的 FieldGroup |
| 可折叠分区 | 使用 @expo/ui 中的 Collapsible |
List不是虚拟化滚动列表。 它会渲染原生分组表格行——外观类似 iOS 设置屏幕或表单分区,并带有指示标记和原生行样式。每个ListItem都是 JS 线程上的原生节点;各行不会被回收。对于数据量大或长度未知的列表(动态信息流、搜索结果、目录),请改用FlatList或FlashList。List适用于较短且长度固定的分组,例如设置屏幕、详情面板中的行或固定菜单。
BottomSheet 示例(用于地图标记详情、操作面板、详情面板——不要使用 Reanimated):
import { Host, BottomSheet, Column, Text } from '@expo/ui';
import { useState } from 'react';
export default function MapScreen() {
const [isOpen, setIsOpen] = useState(false);
return (
<View style={{ flex: 1 }}>
<MapView onMarkerPress={() => setIsOpen(true)} />
<Host>
<BottomSheet
isPresented={isOpen}
onDismiss={() => setIsOpen(false)}
snapPoints={['half', 'full']}
>
<Column>
<Text>Café name</Text>
<Text>Address</Text>
</Column>
</BottomSheet>
</Host>
</View>
);
}
BottomSheet 使用 isPresented/onDismiss——不使用 isOpened、isOpen、onIsOpenedChange 或 onChange(这些是 @gorhom/bottom-sheet 的属性,使用后不会产生任何效果)。snapPoints 可接受 'half'、'full'、{ fraction: 0.5 } 或 { height: 400 },且为可选属性(省略时会根据内容自动调整大小)。
选择方案
按顺序查看以下列表,选择第一个满足需求的层:
-
通用组件——从这里开始。 从
@expo/ui根包导入。一个组件树即可通过单一代码源在 iOS、Android 和 Web 上运行,无需修改(Android 使用 Compose,iOS 使用 SwiftUI,Web 使用react-native-web/react-dom)。无需拆分平台文件。→./references/universal.md -
平台专属(SwiftUI / Jetpack Compose)。 从
@expo/ui/swift-ui或@expo/ui/jetpack-compose导入。仅当通用层缺少所需的组件或修饰符,或需要平台专属行为或优化时使用。**缺点:**你需要编写两套组件树,并将它们拆分到.ios.tsx/.android.tsx文件中(或根据Platform.OS分支处理)——需要维护更多代码。@expo/ui/swift-ui仅适用于 iOS。@expo/ui/jetpack-compose仅适用于 Android。 在另一个平台上运行的文件中导入其中任一项,都会在运行时因 "Unable to get view config" 错误而崩溃。请将平台专属组件树隔离在components/中的.ios.tsx/.android.tsx文件内(切勿放在app/中——Expo Router 不支持路由文件使用平台扩展名),或在普通路由文件中通过Platform.OS进行判断。Host必须始终从@expo/ui(通用包根目录)导入,而不是从平台专属子包导入。→./references/swift-ui.md和./references/jetpack-compose.md
已经在使用 React Native 社区 UI 库? @expo/ui 也提供了可直接替换的组件——与热门库 API 兼容的替代品(@gorhom/bottom-sheet、@react-native-community/datetimepicker 等),从 @expo/ui/community/<name> 导入。这是一条用于替换现有依赖的迁移路径,并非上述通用层与平台专属方案选择流程中的步骤。→ ./references/drop-in-replacements.md
参考资料
按需查阅以下资源:
references/
universal.md Universal @expo/ui components and when to use them (SDK 56+)
drop-in-replacements.md API-compatible replacements for RN community UI libraries
swift-ui.md Platform-specific iOS UI: @expo/ui/swift-ui components, modifiers, RNHostView, useNativeState
jetpack-compose.md Platform-specific Android UI: @expo/ui/jetpack-compose components, modifiers, LazyColumn caveat, icons, useNativeState
提交反馈
如果你发现此技能中存在错误、误导性信息或过时信息,请报告,以便 Expo 加以改进:
npx --yes @expo/agent-cli@latest feedback --category skills --subject "expo-ui" "<actionable feedback>"
只有在有具体且可操作的内容需要报告时才提交。请尽可能提供相关背景信息。
如果 Agent 反复无法完成 Expo 任务,或用户不得不介入,请使用 --category evals 和相关 Expo 包或命令作为 --subject,简要报告任务、预期结果以及出错之处。