← 返回首页

React Native 导航方案:React Navigation 完全指南

Stack、Tab、Drawer 三种导航模式实战,深度讲解嵌套路由、参数传递与导航守卫的最佳实践。

安装

npm install @react-navigation/native
npm install react-native-screens react-native-safe-area-context

# Stack 导航
npm install @react-navigation/native-stack

# Tab 导航
npm install @react-navigation/bottom-tabs

# Drawer 导航
npm install @react-navigation/drawer react-native-gesture-handler react-native-reanimated

在项目根节点包裹 NavigationContainer

// App.tsx
import { NavigationContainer } from '@react-navigation/native';

export default function App() {
  return (
    <NavigationContainer>
      {/* 导航结构 */}
    </NavigationContainer>
  );
}

Stack Navigator — 页面堆栈

Stack 导航模拟原生页面跳转,iOS 从右滑入,Android 从底部弹出。

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

type RootStackParamList = {
  Home: undefined;
  Detail: { id: number; title: string };
};

const Stack = createNativeStackNavigator<RootStackParamList>();

function RootStack() {
  return (
    <Stack.Navigator
      screenOptions={{
        headerStyle: { backgroundColor: '#0a0f1e' },
        headerTintColor: '#e2e8f0',
      }}
    >
      <Stack.Screen name="Home" component={HomeScreen} options={{ title: '首页' }} />
      <Stack.Screen name="Detail" component={DetailScreen} />
    </Stack.Navigator>
  );
}

Tab Navigator — 底部标签栏

import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';

const Tab = createBottomTabNavigator();

function TabNavigator() {
  return (
    <Tab.Navigator
      screenOptions={({ route }) => ({
        tabBarIcon: ({ color, size }) => {
          const icons: Record<string, string> = {
            Home: '🏠', Articles: '📝', Profile: '👤',
          };
          return <Text style={{ fontSize: size, color }}>{icons[route.name]}</Text>;
        },
        tabBarStyle: { backgroundColor: '#111827', borderTopColor: '#1e3a5f' },
        tabBarActiveTintColor: '#3b82f6',
        tabBarInactiveTintColor: '#64748b',
      })}
    >
      <Tab.Screen name="Home" component={HomeScreen} />
      <Tab.Screen name="Articles" component={ArticlesScreen} />
      <Tab.Screen name="Profile" component={ProfileScreen} />
    </Tab.Navigator>
  );
}

Drawer Navigator — 侧边抽屉

import { createDrawerNavigator } from '@react-navigation/drawer';

const Drawer = createDrawerNavigator();

function DrawerNavigator() {
  return (
    <Drawer.Navigator
      screenOptions={{
        drawerStyle: { backgroundColor: '#111827', width: 240 },
        drawerActiveTintColor: '#3b82f6',
      }}
    >
      <Drawer.Screen name="Home" component={HomeScreen} />
      <Drawer.Screen name="Settings" component={SettingsScreen} />
    </Drawer.Navigator>
  );
}

嵌套路由

真实 App 通常是 Stack 嵌套 Tab,或 Tab 内嵌 Stack:

// Tab 嵌套在 Stack 内
function RootStack() {
  return (
    <Stack.Navigator screenOptions={{ headerShown: false }}>
      <Stack.Screen name="Main" component={TabNavigator} />
      <Stack.Screen name="Modal" component={ModalScreen} />
    </Stack.Navigator>
  );
}

参数传递

// 跳转并传参
navigation.navigate('Detail', { id: 42, title: '文章标题' });

// 在目标页面接收
function DetailScreen({ route, navigation }) {
  const { id, title } = route.params;
  return <Text>{title}</Text>;
}

// TypeScript 类型安全版本
import { NativeStackScreenProps } from '@react-navigation/native-stack';

type Props = NativeStackScreenProps<RootStackParamList, 'Detail'>;

function DetailScreen({ route }: Props) {
  const { id, title } = route.params; // 完全类型推导
}

导航守卫(权限控制)

// 根据登录状态动态渲染不同 Navigator
function RootNavigator() {
  const { isLoggedIn } = useAuth();

  return (
    <Stack.Navigator screenOptions={{ headerShown: false }}>
      {isLoggedIn ? (
        <Stack.Screen name="Main" component={TabNavigator} />
      ) : (
        <Stack.Screen name="Auth" component={AuthNavigator} />
      )}
    </Stack.Navigator>
  );
}
💡 最佳实践

用 TypeScript 为所有路由定义 ParamList,可以在编译期检测参数类型错误,避免运行时的页面跳转问题。这是 React Navigation 最值得利用的特性之一。