Skip to content

Expo Router

Expo Router 基于文件系统生成 Android、iOS 和 Web 路由。src/app 中的页面具有与文件位置对应的路径,并自动支持 Deep Link。

路由约定

bash
src/app/
├── _layout.tsx            # 根布局
├── index.tsx              # /
├── settings.tsx           # /settings
├── users/
   └── [id].tsx           # /users/:id
└── (tabs)/                # 路由组,不进入 URL
    ├── _layout.tsx
    ├── home.tsx           # /home
    └── profile.tsx        # /profile
  • 页面必须默认导出 React 组件;
  • _layout.tsx 定义目录下页面的导航关系;
  • index.tsx 对应该目录的默认路由;
  • [id].tsx 表示动态参数;
  • (group) 用于组织布局,不会成为 URL 片段。

Stack

tsx
import { Stack } from 'expo-router'

export default function RootLayout() {
  return (
    <Stack>
      <Stack.Screen name="index" options={{ title: '首页' }} />
      <Stack.Screen name="users/[id]" options={{ title: '用户' }} />
    </Stack>
  )
}

根布局也是放置主题 Provider、字体加载、启动屏控制和全局状态初始化的位置。

Tabs

标签页由目录布局声明:

tsx
import { Tabs } from 'expo-router'

export default function TabsLayout() {
  return (
    <Tabs>
      <Tabs.Screen name="home" options={{ title: '首页' }} />
      <Tabs.Screen name="profile" options={{ title: '我的' }} />
    </Tabs>
  )
}

导航与参数

声明式导航使用 Link

tsx
import { Link } from 'expo-router'

export function UserLink({ id }: { id: string }) {
  return <Link href={{ pathname: '/users/[id]', params: { id } }}>查看用户</Link>
}

动态页面通过 useLocalSearchParams 读取参数:

tsx
import { useLocalSearchParams } from 'expo-router'
import { Text } from 'react-native'

export default function UserPage() {
  const { id } = useLocalSearchParams<{ id: string }>()

  return <Text>用户 ID:{id}</Text>
}

命令式导航使用 router.pushrouter.replacerouter.back。登录完成后通常使用 replace,避免返回到登录页。

应用配置中的 scheme 定义自有协议。生产环境还可以配置 Android App Links 和 iOS Universal Links。路由参数来自外部链接时必须视为不可信输入,并在使用前校验。

参考资料

基于 MIT 许可发布