React Navigation
React Native 官方推荐的路由库,由 Software Mansion 和 Expo 工程师共同维护。React Navigation 与 React Router / TanStack Router 不同——它专为 React Native 设计,不是 Web 路由库;URL 这个概念在原生 App 中并不直接对应屏幕(虽然支持 Deep Linking 反向映射),路由对象更接近「屏幕栈」与「导航器树」的组合。React Navigation 现处于 7.x 时代(2024-2026 主线,包名 @react-navigation/native@^7、@react-navigation/native-stack@^7 等),要求 React Native ≥ 0.72 / Expo ≥ 52 / TypeScript ≥ 5.0;2025 年起新增 Static Configuration API(createStaticNavigation)作为推荐入口,与传统的 NavigationContainer + Navigator + Screen 动态写法并存。核心特性矩阵:五大 Navigator(Native Stack @react-navigation/native-stack 走 iOS UINavigationController / Android Fragment 原生平台导航 / Stack @react-navigation/stack 纯 JS 实现可深度定制转场 / Bottom Tabs @react-navigation/bottom-tabs 底部 tab 栏 / Drawer @react-navigation/drawer 侧滑抽屉,需 Reanimated 2+ / Material Top Tabs @react-navigation/material-top-tabs 顶部 tab + 滑动切换,基于 react-native-tab-view) / NavigationContainer 顶层包装(提供 linking / theme / onStateChange / initialState 持久化) / 嵌套 Navigator(Tabs 包 Stacks 是最常用模式:进入二级页时 tabbar 仍可见) / TypeScript Type-safe Routes(声明 RootStackParamList + NativeStackScreenProps<ParamList, 'RouteName'> 即可获得 route.params / navigation.navigate(...) 完整类型推导 / 全局类型扩展 declare global { namespace ReactNavigation { interface RootParamList ... } } 让 useNavigation() 也自动推导) / Deep Linking(prefixes + config.screens 把 URL 映射回屏幕栈,支持 getInitialURL / subscribe 接管 Push Notification 唤起的链接) / Authentication Flow(条件渲染 Navigator 模式:登录 / 未登录两个 Stack 互斥,登录态变化时 React Navigation 自动跳转,无需 navigate('Login')) / State Persistence(AsyncStorage 配合 initialState + onStateChange 持久化整棵导航树) / 预设 Header(headerStyle / headerTintColor / headerTitle / headerRight / headerLeft / headerLargeTitle iOS 大标题等) / Tab 自定义(tabBarIcon / tabBarBadge / tabBarStyle,v7 起支持 tabBarPosition: 'left' 大屏侧栏) / 转场动画(Native Stack presentation: 'modal' | 'transparentModal' | 'formSheet' | 'fullScreenModal' + animation: 'slide_from_right' | 'fade' | 'slide_from_bottom' | 'none' / JS Stack TransitionPresets + cardStyleInterpolator 全自定义) / Hook 体系(useNavigation / useRoute / useFocusEffect 屏幕聚焦副作用 / useIsFocused 当前是否聚焦 / useDrawerStatus / useDrawerProgress) / Screen 事件(focus / blur / beforeRemove 拦截返回 / tabPress / tabLongPress / drawerItemPress) / Screen Preloading(v7 新增 navigation.preload() 提前渲染屏幕,提升点击 → 显示时延) / Layout Props(v7 新增 layout / screenLayout 包裹整组导航器或单屏,用于 Provider 注入等场景)。与 Expo Router 的关系:Expo Router(7.x+)是 基于 React Navigation 构建 的 file-based 路由框架——把 app/ 目录约定为路由表(类似 Next.js App Router 在 Web 端的角色),底层仍然是 @react-navigation/native-stack / @react-navigation/bottom-tabs。两者不冲突、可选择:手写 Stack.Navigator 配置 = React Navigation 原生用法;写 app/(tabs)/index.tsx 文件 = Expo Router 风格。Expo SDK 50+ 起 Expo Router 是新项目的默认推荐,但所有底层 API(useRouter / useLocalSearchParams / Stack.Screen)都是对 React Navigation 的薄包装。典型用户群:所有大型 React Native 应用——Facebook / Instagram / Discord / Coinbase / Shopify Mobile / Bluesky / 微软 Office Mobile 等绝大多数 RN App;Expo 生态默认推荐。
评价
优点
- React Native 官方钦定 + Software Mansion 主导:与
react-native-screens/react-native-reanimated/react-native-gesture-handler同一团队,原生层与 JS 层深度协同 - Native Stack 走原生导航控制器:iOS
UINavigationController/ AndroidFragment原生转场——比纯 JS Stack 性能高 1 个数量级、获得 iOS 大标题 / 滑动返回 / 形式 sheet 等原生特性 - 5 种 Navigator 覆盖全部交互模式:Native Stack / JS Stack / Bottom Tabs / Drawer / Material Top Tabs 一应俱全——可任意嵌套组合(Tabs 包 Stacks 是 RN App 95% 的模式)
- 嵌套 Navigator 一等公民:导航事件先在当前 Navigator 处理、再冒泡到父级——
goBack()自动尊重最近的栈,无需手写状态机 - TypeScript 类型化完整:
NativeStackScreenProps/RouteProp/NavigationProp全套泛型、CompositeNavigationProp处理嵌套——全局扩展ReactNavigation.RootParamList让useNavigation()也类型安全 - Authentication Flow 是状态驱动:登录 / 未登录写两个 Stack、用
isSignedIn切换——React Navigation 自动播放转场,无需navigate('Login')手动跳转、也不会有「按返回回到登录页」的安全漏洞 - Deep Linking 配置化:
linking.prefixes + config.screens一份配置同时管理 URI Scheme(myapp://...)与 Universal Link(https://app.example.com/...),支持 Push Notification 唤起、命中后还能完美还原嵌套栈 - State Persistence 简单可靠:
initialState+onStateChange+AsyncStorage三件套——开发期可保存导航位置、Hot Reload 不丢失浏览状态 useFocusEffect解决 RN 长期痛点:屏幕聚焦时跑副作用、失焦时清理——比useEffect多了「屏幕在栈中但不可见」这个 RN 独有生命周期感知- 预设转场 + 完全自定义:Native Stack 的
presentation+animation字符串预设覆盖 90% 场景;需要更深定制时切到 JS Stack 用cardStyleInterpolator写 Reanimated 插值 - Header 系统强大:
headerRight/headerLeft/headerTitle接收函数返回组件、navigation.setOptions({ headerRight })在屏幕内动态更新——配合Button from '@react-navigation/elements'自动适配明暗主题 beforeRemove事件拦截返回:表单未保存时弹确认对话框——这是 RN 长期缺失、v6 才补齐的核心能力- Static API + Dynamic API 并存:v7 新增
createStaticNavigation,对象配置 + 自动 TypeScript 类型 + 自动 Linking——文档优先推荐;老项目可继续用NavigationContainer + Navigator + Screen动态写法 - Expo Router 反哺生态:所有 React Navigation API 都被 Expo Router 完整暴露(
useRouter/useLocalSearchParams/Stack.Screen)——选择 file-based 与 config-based 不用换库 - 生态成熟:
@react-navigation/elements提供 Header / Button / Label 组件;社区有react-navigation-shared-element共享元素转场、@bottom-tabs/react-navigation真原生 tabbar 等扩展
缺点
- Native Stack 不能完全自定义转场:用原生平台导航控制器,转场动画就那几个字符串(
slide_from_right/fade/slide_from_bottom);需要 Shared Element / 自定义曲线只能用 JS Stack - JS Stack 性能低:纯 JS 实现的
@react-navigation/stack在低端 Android 上滑动返回掉帧;除非确实需要深度定制,否则推荐用 Native Stack - Drawer 必须 Reanimated 2+:
@react-navigation/drawerv7 起强依赖react-native-reanimated/react-native-gesture-handler——RN 0.71 之前的项目难升级 - 嵌套层级深时心智成本高:3+ 层嵌套(如 Drawer 包 Tabs 包 Stack)时
navigation.navigate('A', { screen: 'B', params: { screen: 'C' } })写起来痛苦;事件冒泡 / 选项隔离 / params 作用域容易踩坑——官方建议尽量降低嵌套深度 - v6 → v7 破坏性变更多:
navigate()不再回退到已存在屏幕(需用popTo)/navigate()不再支持直接跳嵌套子 screen 名 /NavigationContainer.theme现在必须含fonts/unmountOnBlur改为popToTopOnBlur——升级前必读 Upgrade Guide - Web 支持有限:React Navigation 支持
react-native-web但转场体验、URL 处理、SEO 远不如 React Router / TanStack Router——RN 跑 Web 时建议改用 Expo Router 或 Solito 这类桥接方案 - iOS 滑动返回与 React Reanimated 共享元素冲突:Native Stack 的
gestureEnabled与第三方共享元素库可能互相干扰,需自行做手势协调 - TypeScript 全局扩展易遗漏:
declare global { namespace ReactNavigation { interface RootParamList ... } }必须放在某个被加载的.ts文件中——新人常忘记导致useNavigation()不带类型 - Static API 仍在演进:
createStaticNavigation是 v7 新增、未完全替代 Dynamic 写法;某些高级特性(如运行时增删 screen)只能用 Dynamic - 不能像 Web 路由那样「直接跳到任意路径」:
navigation.navigate('Details')跳的是当前 Navigator 内的 screen 名——跨 Navigator 跳转必须显式写navigation.navigate('TabA', { screen: 'Details' }),没有「全局 URL」的概念 - vs Expo Router:Expo Router 7+ 用
app/目录约定式路由(类似 Next.js App Router)——开发体验更现代、Type-safe Routes 编译期生成;但底层仍是 React Navigation,两者并非替代关系,对原生交互的精细控制(自定义 header、深嵌套)还是 React Navigation 原生用法更直接 - vs React Router:React Router 7 是 Web 路由库、用浏览器 URL;React Navigation 是原生路由库、用屏幕栈——两者完全不对应,不可直接迁移。RN + Web 同构项目建议 Solito 或 Expo Router
文档地址
React Navigation 官网 | Getting Started | Hello React Navigation | Native Stack Navigator | Bottom Tab Navigator | Drawer Navigator | TypeScript | Deep Linking | Authentication Flow | State Persistence | Upgrading from 6.x
GitHub 地址
react-navigation/react-navigation | software-mansion/react-native-screens(Native Stack 底层)| expo/expo-router(Expo Router 7+ file-based 路由)
学习路径
- 入门:版本与依赖矩阵 /
pnpm add @react-navigation/native @react-navigation/native-stack安装 /react-native-screens+react-native-safe-area-contextpeer deps / Native Stack 第一个示例 /NavigationContainer顶层包装 /Stack.Navigator+Stack.Screen/navigation.navigate/ 传 params /route.params接收 /initialParams默认值 /setParams更新 / Bottom Tabs 第二步 / TypeScriptRootStackParamList与NativeStackScreenProps基础用法 - 指南:核心:5 种 Navigator 详解(Native Stack / JS Stack / Bottom Tabs / Drawer / Material Top Tabs)+ Native Stack vs JS Stack 选型 / 嵌套 Navigator 模式(Tabs 包 Stacks / Drawer 包 Tabs 包 Stacks / Modal Stack 平级模式) / 完整 TypeScript 类型系统(
RootStackParamList/NativeStackScreenProps/RouteProp/CompositeNavigationProp/CompositeScreenProps/ 全局ReactNavigation.RootParamList扩展) / Header 完全自定义(headerRight/headerLeft/navigation.setOptions动态 /Button from @react-navigation/elements) / 转场动画(Native Stack presentation + animation 预设 / JS StackTransitionPresets/cardStyleInterpolatorReanimated) / Modal Stack(presentation: 'modal' | 'transparentModal' | 'formSheet') / Tab Bar 自定义(tabBarIcon/tabBarBadge/ 响应式tabBarPosition: 'left') / Drawer 自定义(drawerContent/useDrawerStatus) / Deep Linking(URI Scheme + Universal Link + 自定义getInitialURL/subscribe) / Authentication Flow(条件渲染 Navigator 模式 /useReducer三态机 / SecureStore Token 持久化) / State Persistence(initialState+onStateChange+AsyncStorage) /useFocusEffect屏幕聚焦副作用 /useIsFocused/beforeRemove拦截返回 / Screen Preloading / Static API(createStaticNavigation)vs Dynamic API / v6 → v7 迁移要点 / 与 Expo Router 对比与共存 / 与 React Router 对比 - 参考:API 速查:
createNativeStackNavigator/createStackNavigator/createBottomTabNavigator/createDrawerNavigator/createMaterialTopTabNavigator/createStaticNavigation全签名 /NavigationContainerprops 完整列表 /useNavigation/useRoute/useFocusEffect/useIsFocused完整签名 /useDrawerStatus/useDrawerProgress/navigation方法(navigate/push/pop/popTo/popToTop/replace/goBack/reset/setParams/setOptions/dispatch/isFocused/canGoBack/getParent/getState/preload) /navigation.addListener事件(focus/blur/beforeRemove/tabPress/tabLongPress/drawerItemPress) / Native Stack screen options 全表(headerXxx/presentation/animation/gestureEnabled/statusBarStyle/navigationBarColor) / Bottom Tabs screen options(tabBarLabel/tabBarIcon/tabBarBadge/tabBarStyle/tabBarPosition/tabBarHideOnKeyboard) / Drawer screen options(drawerType/drawerPosition/drawerStyle/drawerContent) /linking配置对象 /theme对象 +DefaultTheme/DarkTheme/ Param List 类型(NavigatorScreenParams/ParamListBase/RouteProp/NativeStackScreenProps/BottomTabScreenProps/DrawerScreenProps/CompositeNavigationProp/CompositeScreenProps) / 全局类型扩展模板