页面栈与路由:React Navigation 与 Expo Router 深度实践

55 阅读2分钟

1. 移动端路由的概念映射

在原生 Android 中,页面的管理主要依赖于基于 Activity 的回退栈(Back Stack)或者基于 Fragment / Navigation Component 的导航图(NavGraph)。 在 Jetpack Compose 中,我们通常使用 Navigation for Compose

在 React Native 中,最主流的导航库是 React Navigation,而伴随着 Expo 的兴起,基于文件系统的 Expo Router 正在成为新的趋势。

2. React Navigation:经典的基于代码的路由

React Navigation 类似于 Android 的 Navigation Component,你需要在代码中显式声明所有的路由和页面栈。

核心概念:

  • Stack Navigator: 类似于 Android 的 Activity 栈,页面一层层叠加,按返回键出栈。
  • Tab Navigator: 类似于带有 BottomNavigationView 的主界面,通常作为应用的根页面之一。

与 Android Compose Navigation 的对比

Compose Navigation:

val navController = rememberNavController()
NavHost(navController, startDestination = "home") {
    composable("home") { HomeScreen(navController) }
    composable("details/{id}") { backStackEntry ->
        DetailsScreen(id = backStackEntry.arguments?.getString("id"))
    }
}
// 导航
navController.navigate("details/123")

React Navigation:

const Stack = createNativeStackNavigator();
​
function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator initialRouteName="Home">
        <Stack.Screen name="Home" component={HomeScreen} />
        <Stack.Screen name="Details" component={DetailsScreen} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}
// 导航
navigation.navigate('Details', { id: 123 });

两者非常相似,都需要一个统一的地方注册所有路由,并通过 Controller/navigation 对象进行跳转。

3. 现代趋势:Expo Router(基于文件系统的路由)

如果你做过 Next.js 或者传统的 Web 开发,会熟悉基于文件系统的路由。Expo Router 将这一概念引入了 RN。 它不再需要像 React Navigation 那样写长长的注册代码,而是目录结构即路由

它是如何工作的?

  • app/index.tsx 对应路由 /
  • app/details.tsx 对应路由 /details
  • app/user/[id].tsx 对应动态路由 /user/123

这种方式极大地简化了深层链接(Deep Linking)的处理。在传统的 Android 中,处理 Deep Link 需要在 AndroidManifest.xml 中配置 Intent Filter,并在 Activity 中解析 URI。在 Expo Router 中,Deep Link 是开箱即用的,因为路由本来就是以 URL 形式组织的。

4. 我们应该选哪个?

  • 如果你在维护一个现有的纯 RN 项目,React Navigation 是唯一解。
  • 如果你启动一个全新的项目并使用了 Expo(强烈推荐),Expo Router 是最佳选择。它底层依然基于 React Navigation,但封装了繁琐的配置,带来了更好的开发体验。