Expo Router是Expo官方提供的路由解决方案,基于文件系统路由,专为Expo应用设计。它简化了导航管理,提供了类型安全的路由和深度链接支持。
核心特性:
-
文件系统路由
- 基于文件和文件夹结构自动生成路由
- 支持动态路由和嵌套路由
- 类似Next.js的路由体验
-
类型安全
- 自动生成TypeScript类型
- 编译时路由检查
- 智能代码补全
-
深度链接
- 原生深度链接支持
- Web URL兼容
- 自动处理链接参数
安装和配置:
bash# 安装Expo Router npx expo install expo-router react-native-safe-area-context react-native-screens expo-linking expo-constants expo-status-bar # 配置app.json { "expo": { "scheme": "myapp", "experiments": { "typedRoutes": true } } }
项目结构:
shellapp/ ├── _layout.tsx # 根布局 ├── index.tsx # 首页 (/) ├── about.tsx # 关于页面 (/about) ├── user/ │ ├── [id].tsx # 用户详情页 (/user/:id) │ └── settings.tsx # 用户设置 (/user/settings) ├── (tabs)/ │ ├── _layout.tsx # Tab布局 │ ├── home.tsx # Tab首页 │ └── profile.tsx # Tab个人页 └── (modal)/ └── _layout.tsx # Modal布局
路由类型:
- 静态路由
typescript// app/index.tsx export default function HomeScreen() { return <Text>Home</Text>; }
- 动态路由
typescript// app/user/[id].tsx import { useLocalSearchParams } from 'expo-router'; export default function UserScreen() { const { id } = useLocalSearchParams<{ id: string }>(); return <Text>User: {id}</Text>; }
- 嵌套路由
typescript// app/(tabs)/_layout.tsx import { Tabs } from 'expo-router'; export default function TabLayout() { return ( <Tabs> <Tabs.Screen name="home" options={{ title: 'Home' }} /> <Tabs.Screen name="profile" options={{ title: 'Profile' }} /> </Tabs> ); }
- 分组路由
typescript// (tabs)和(modal)是路由组,不影响URL // app/(tabs)/home.tsx -> /home // app/(modal)/settings.tsx -> /settings
导航API:
typescriptimport { useRouter, useSegments } from 'expo-router'; function MyComponent() { const router = useRouter(); const segments = useSegments(); // 导航到页面 const navigateToUser = () => { router.push('/user/123'); }; // 替换当前页面 const replacePage = () => { router.replace('/settings'); }; // 返回上一页 const goBack = () => { router.back(); }; // 检查当前路由 const isHome = segments[0] === 'home'; return ( <View> <Button title="Go to User" onPress={navigateToUser} /> <Button title="Replace" onPress={replacePage} /> <Button title="Back" onPress={goBack} /> </View> ); }
链接API:
typescriptimport { Link, useLocalSearchParams } from 'expo-router'; // 使用Link组件 <Link href="/user/123"> <Text>Go to User</Text> </Link> // 使用useLocalSearchParams获取参数 const { id } = useLocalSearchParams<{ id: string }>();
深度链接配置:
typescript// app/_layout.tsx import { Stack } from 'expo-router'; import * as Linking from 'expo-linking'; const linking = { prefixes: [Linking.createURL('/')], config: { screens: { index: '/', user: '/user/:id', }, }, }; export default function RootLayout() { return <Stack />; }
最佳实践:
-
路由组织:合理使用路由组和嵌套布局,保持结构清晰
-
类型安全:启用typedRoutes实验性功能,获得完整的类型支持
-
性能优化:使用懒加载减少初始包大小
-
错误处理:实现404页面和错误边界
-
测试覆盖:为路由逻辑编写单元测试
与React Navigation的对比:
Expo Router基于React Navigation构建,提供了更高级的抽象:
- 更简单的配置
- 自动类型生成
- 文件系统路由
- 更好的深度链接支持
Expo Router是构建Expo应用导航的理想选择,特别适合需要类型安全和深度链接的项目。