第2章 React Navigation 6 环境搭建:安装依赖、配置导航容器、项目结构

本章聚焦 React Navigation 6 的入门搭建流程。状态保持并非凭空生效,它依赖正确的导航容器、屏幕注册及底层协调机制。若基础环境配置不当,后续所有 `useIsFocused`、`useFocusEffect` 及 `useEffect` 组合都会产生不可预测的行为。本章通过可复现的命令、容器代码和项目骨架,为你搭建一个“状态保持就绪”的开发底座。

2.1 状态保持对环境的基本要求

层面要求原因
导航库版本React Navigation 6.x(稳定版)6.x 内置 Focus 钩子与屏幕生命周期,是状态保持的核心
React 版本React 16.8+(推荐 18.x)Hooks 支持,useIsFocused / useFocusEffect 依赖
原生模块react-native-screens, react-native-safe-area-context提供原生屏幕堆栈与安全区域,避免状态闪白
Bundle 工具Metro / Expo Go标准工具链,无需额外配置
💡 版本提示
React Navigation 6 是当前推荐的大版本。5.x 已停止维护,7.x 处于早期预览阶段。本章所有代码基于 React Native 0.72 + React Navigation 6.x。

2.2 安装依赖

2.2.1 核心包

npm install @react-navigation/native @react-navigation/native-stack @react-navigation/bottom-tabs

2.2.2 原生依赖(React Native CLI 项目)

npm install react-native-screens react-native-safe-area-context
cd ios && pod install && cd ..

2.2.3 Expo 项目(无需 pod install)

npx expo install react-native-screens react-native-safe-area-context
🔥 关键动作
安装后务必重新启动打包器(npx react-native start --reset-cache 或 expo start -c),否则原生模块可能不被正确链接。

2.3 配置导航容器

导航容器是整个应用状态树的根节点。React Navigation 6 使用 NavigationContainer 包装应用,它内部维护焦点状态、URL 映射及内存管理。

import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';

const Stack = createNativeStackNavigator();

function AppNavigator() {
  return (
    <NavigationContainer>
      <Stack.Navigator initialRouteName="Home">
        <Stack.Screen name="Home" component={HomeScreen} />
        <Stack.Screen name="Details" component={DetailsScreen} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

export default function App() {
  return <AppNavigator />;
}
⚠️ 常见错误
• 忘记包裹 NavigationContainer 会导致 useIsFocused 返回 undefined。
• 使用 createNativeStackNavigator 时必须已安装 react-native-screens,否则抛出“NativeStackNavigator is not registered”错误。

2.4 推荐项目结构

保持容器、屏幕、导航配置分离,有利于后续状态保持逻辑(如 Context、Redux、Zustand)的独立注入。

src/
├── navigation/
│   ├── AppNavigator.js       # 导航容器 + 导航列表
│   ├── linkingConfig.js      # Deep Linking 配置(状态保持需要)
│   └── hooks/
│       └── useKeepState.js   # 未来状态保持自定义 Hook
├── screens/
│   ├── HomeScreen.js
│   └── DetailsScreen.js
├── store/                    # 全局状态(状态保持目标)
│   ├── index.js
│   └── slices/
│       └── navigationSlice.js
├── components/
│   └── KeepAliveWrapper.js   # 状态保持容器组件
└── App.js                    # 入口:渲染 AppNavigator

2.5 调试技巧 & 常见错误

  • 调试焦点状态:在屏幕组件中添加 console.log('isFocused:', useIsFocused()),观察进出栈时变化。
  • 检查依赖版本:使用 npx react-native info 或 npx expo-env-info 确认包版本兼容。
  • 常见错误 #1:React Native Screens 未安装 → 导航栈无动画,屏幕全白。解决方案:重新 pod install 并清理缓存。
  • 常见错误 #2:多个 NavigationContainer 嵌套使用 → 状态混乱。解决方案:始终在应用根层只用 一个 NavigationContainer。
🛠 调试辅助工具
React Navigation 6 提供 @react-navigation/devtools(仅开发模式),安装后可在应用内显示导航状态树。
npm install @react-navigation/devtools
// 在 AppNavigator 中引入:
import { useNavigationContainerRef } from '@react-navigation/native';
import { useFlipper } from '@react-navigation/devtools';

2.6 本章小结:从环境到状态保持的桥梁

下面是 React Navigation 6 容器与状态保持关键组件的关系图——注意 NavigationContainer 作为全局焦点源,向上连接状态管理库(如 Redux/Zustand),向下驱动屏幕切换。

React Navigation 6 状态保持环境图 Zustand / Redux 全局状态(保持目标) NavigationContainer 焦点 / URL / 嵌套管理 原生模块 screens / safe-area HomeScreen useIsFocused DetailsScreen useIsFocused KeepAlive 状态保持容器 状态保持管道 NavigationContainer 作为焦点源 → 屏幕通过 useIsFocused 感知 → KeepAliveWrapper 缓存上次状态