ReactNative导航技能Skill react-native-navigation

这个技能用于在 React Native 移动应用中实现导航功能,涵盖堆栈导航、标签导航、抽屉导航、深度链接和常见导航模式。关键词:React Native, 导航, 移动开发, React Navigation, 堆栈导航, 标签导航, 抽屉导航, 深度链接, 类型安全导航, 认证流程, 深度链接配置。

移动开发 0 次安装 0 次浏览 更新于 3/25/2026

名称: react-native-navigation 用户可调用: false 描述: 在使用 React Navigation 在 React Native 应用中实现导航时使用。涵盖堆栈导航、标签导航、抽屉导航、深度链接和导航模式。 允许工具:

  • 读取
  • 写入
  • 编辑
  • Bash
  • Grep
  • Glob

React Native 导航

在使用 React Navigation(事实上的标准导航库)在 React Native 应用程序中实现导航时使用此技能。

关键概念

安装

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

# 对于堆栈导航
npm install @react-navigation/native-stack

# 对于标签导航
npm install @react-navigation/bottom-tabs

# 对于抽屉导航
npm install @react-navigation/drawer react-native-gesture-handler react-native-reanimated

基本设置

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

type RootStackParamList = {
  Home: undefined;
  Details: { itemId: string };
};

const Stack = createNativeStackNavigator<RootStackParamList>();

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

堆栈导航

最常见的导航模式:

import React from 'react';
import { View, Text, Button } from 'react-native';
import { NativeStackScreenProps } from '@react-navigation/native-stack';

type RootStackParamList = {
  Home: undefined;
  Details: { itemId: string; title: string };
};

type HomeProps = NativeStackScreenProps<RootStackParamList, 'Home'>;
type DetailsProps = NativeStackScreenProps<RootStackParamList, 'Details'>;

function HomeScreen({ navigation }: HomeProps) {
  return (
    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
      <Text>首页</Text>
      <Button
        title="前往详情"
        onPress={() =>
          navigation.navigate('Details', {
            itemId: '123',
            title: '我的项目',
          })
        }
      />
    </View>
  );
}

function DetailsScreen({ route, navigation }: DetailsProps) {
  const { itemId, title } = route.params;

  return (
    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
      <Text>详情页面</Text>
      <Text>项目ID: {itemId}</Text>
      <Text>标题: {title}</Text>
      <Button title="返回" onPress={() => navigation.goBack()} />
    </View>
  );
}

标签导航

底部标签用于主要导航:

import React from 'react';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { Ionicons } from '@expo/vector-icons';

type TabParamList = {
  Home: undefined;
  Search: undefined;
  Profile: undefined;
};

const Tab = createBottomTabNavigator<TabParamList>();

export default function TabNavigator() {
  return (
    <Tab.Navigator
      screenOptions={({ route }) => ({
        tabBarIcon: ({ focused, color, size }) => {
          let iconName: keyof typeof Ionicons.glyphMap;

          if (route.name === 'Home') {
            iconName = focused ? 'home' : 'home-outline';
          } else if (route.name === 'Search') {
            iconName = focused ? 'search' : 'search-outline';
          } else {
            iconName = focused ? 'person' : 'person-outline';
          }

          return <Ionicons name={iconName} size={size} color={color} />;
        },
        tabBarActiveTintColor: '#007AFF',
        tabBarInactiveTintColor: 'gray',
      })}
    >
      <Tab.Screen name="Home" component={HomeScreen} />
      <Tab.Screen name="Search" component={SearchScreen} />
      <Tab.Screen name="Profile" component={ProfileScreen} />
    </Tab.Navigator>
  );
}

最佳实践

类型安全导航

定义导航类型以实现类型安全:

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

// 定义参数列表
type RootStackParamList = {
  Home: undefined;
  Details: { itemId: string };
  UserProfile: { userId: string; name: string };
};

// 声明全局类型
declare global {
  namespace ReactNavigation {
    interface RootParamList extends RootStackParamList {}
  }
}

// 使用类型化属性
type DetailsProps = NativeStackScreenProps<RootStackParamList, 'Details'>;

function DetailsScreen({ route, navigation }: DetailsProps) {
  // route.params 完全类型化
  const { itemId } = route.params;

  // navigation.navigate 类型安全
  navigation.navigate('UserProfile', {
    userId: '123',
    name: 'John',
  });

  return <View />;
}

标题自定义

自定义导航标题:

<Stack.Navigator
  screenOptions={{
    headerStyle: {
      backgroundColor: '#007AFF',
    },
    headerTintColor: '#fff',
    headerTitleStyle: {
      fontWeight: 'bold',
    },
  }}
>
  <Stack.Screen
    name="Home"
    component={HomeScreen}
    options={{
      title: '我的首页',
      headerRight: () => (
        <Button
          onPress={() => console.log('Pressed')}
          title="信息"
          color="#fff"
        />
      ),
    }}
  />
</Stack.Navigator>

动态标题选项

从屏幕设置标题选项:

import { useLayoutEffect } from 'react';

function DetailsScreen({ navigation, route }: DetailsProps) {
  useLayoutEffect(() => {
    navigation.setOptions({
      title: route.params.title,
      headerRight: () => (
        <Button title="保存" onPress={() => console.log('保存')} />
      ),
    });
  }, [navigation, route.params.title]);

  return <View />;
}

嵌套导航器

组合不同导航模式:

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

const HomeStack = createNativeStackNavigator();
const ProfileStack = createNativeStackNavigator();
const Tab = createBottomTabNavigator();

function HomeStackScreen() {
  return (
    <HomeStack.Navigator>
      <HomeStack.Screen name="Home" component={HomeScreen} />
      <HomeStack.Screen name="Details" component={DetailsScreen} />
    </HomeStack.Navigator>
  );
}

function ProfileStackScreen() {
  return (
    <ProfileStack.Navigator>
      <ProfileStack.Screen name="Profile" component={ProfileScreen} />
      <ProfileStack.Screen name="Settings" component={SettingsScreen} />
    </ProfileStack.Navigator>
  );
}

export default function App() {
  return (
    <NavigationContainer>
      <Tab.Navigator>
        <Tab.Screen name="HomeTab" component={HomeStackScreen} />
        <Tab.Screen name="ProfileTab" component={ProfileStackScreen} />
      </Tab.Navigator>
    </NavigationContainer>
  );
}

常见模式

认证流程

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

type RootStackParamList = {
  SignIn: undefined;
  SignUp: undefined;
  Home: undefined;
  Details: { itemId: string };
};

const Stack = createNativeStackNavigator<RootStackParamList>();

export default function App() {
  const [isSignedIn, setIsSignedIn] = useState(false);

  return (
    <NavigationContainer>
      <Stack.Navigator>
        {!isSignedIn ? (
          // 认证页面
          <>
            <Stack.Screen name="SignIn" component={SignInScreen} />
            <Stack.Screen name="SignUp" component={SignUpScreen} />
          </>
        ) : (
          // 应用页面
          <>
            <Stack.Screen name="Home" component={HomeScreen} />
            <Stack.Screen name="Details" component={DetailsScreen} />
          </>
        )}
      </Stack.Navigator>
    </NavigationContainer>
  );
}

深度链接

配置深度链接:

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

const linking = {
  prefixes: ['myapp://', 'https://myapp.com'],
  config: {
    screens: {
      Home: 'home',
      Details: 'details/:itemId',
      UserProfile: 'user/:userId',
    },
  },
};

export default function App() {
  return (
    <NavigationContainer linking={linking}>
      <Stack.Navigator>
        <Stack.Screen name="Home" component={HomeScreen} />
        <Stack.Screen name="Details" component={DetailsScreen} />
        <Stack.Screen name="UserProfile" component={UserProfileScreen} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

模态导航

以模态形式呈现页面:

<Stack.Navigator>
  <Stack.Group>
    <Stack.Screen name="Home" component={HomeScreen} />
    <Stack.Screen name="Details" component={DetailsScreen} />
  </Stack.Group>
  <Stack.Group screenOptions={{ presentation: 'modal' }}>
    <Stack.Screen name="CreatePost" component={CreatePostScreen} />
    <Stack.Screen name="Settings" component={SettingsScreen} />
  </Stack.Group>
</Stack.Navigator>

导航守卫

使用守卫保护路由:

import { useEffect } from 'react';

function ProtectedScreen({ navigation }: any) {
  const isAuthenticated = useAuth(); // 自定义钩子

  useEffect(() => {
    if (!isAuthenticated) {
      navigation.replace('SignIn');
    }
  }, [isAuthenticated, navigation]);

  if (!isAuthenticated) {
    return null; // 或加载页面
  }

  return <View>{/* 受保护内容 */}</View>;
}

自定义标签栏

创建自定义标签栏:

import { View, Text, TouchableOpacity } from 'react-native';

function CustomTabBar({ state, descriptors, navigation }: any) {
  return (
    <View style={{ flexDirection: 'row', height: 60 }}>
      {state.routes.map((route: any, index: number) => {
        const { options } = descriptors[route.key];
        const isFocused = state.index === index;

        const onPress = () => {
          const event = navigation.emit({
            type: 'tabPress',
            target: route.key,
            canPreventDefault: true,
          });

          if (!isFocused && !event.defaultPrevented) {
            navigation.navigate(route.name);
          }
        };

        return (
          <TouchableOpacity
            key={route.key}
            onPress={onPress}
            style={{
              flex: 1,
              justifyContent: 'center',
              alignItems: 'center',
              backgroundColor: isFocused ? '#007AFF' : '#fff',
            }}
          >
            <Text style={{ color: isFocused ? '#fff' : '#000' }}>
              {options.title || route.name}
            </Text>
          </TouchableOpacity>
        );
      })}
    </View>
  );
}

<Tab.Navigator tabBar={(props) => <CustomTabBar {...props} />}>
  <Tab.Screen name="Home" component={HomeScreen} />
  <Tab.Screen name="Profile" component={ProfileScreen} />
</Tab.Navigator>

反模式

不要在 useEffect 中没有依赖项时导航

// 错误 - 无限循环风险
useEffect(() => {
  navigation.navigate('Home');
});

// 正确 - 适当的依赖项
useEffect(() => {
  if (shouldNavigate) {
    navigation.navigate('Home');
  }
}, [shouldNavigate, navigation]);

不要使用 navigate() 来替换页面

// 错误 - 添加到导航堆栈
navigation.navigate('SignIn');

// 正确 - 替换当前页面
navigation.replace('SignIn');

不要在没有类型安全的情况下访问导航

// 错误 - 没有类型安全
function MyScreen({ navigation }: any) {
  navigation.navigate('Detials', { itemId: 123 }); // 拼写错误不会被捕获
}

// 正确 - 类型安全导航
type Props = NativeStackScreenProps<RootStackParamList, 'Home'>;

function MyScreen({ navigation }: Props) {
  navigation.navigate('Details', { itemId: '123' }); // 类型检查
}

不要忘记在 Android 上处理返回按钮

import { useEffect } from 'react';
import { BackHandler } from 'react-native';

function MyScreen({ navigation }: any) {
  useEffect(() => {
    const backHandler = BackHandler.addEventListener(
      'hardwareBackPress',
      () => {
        navigation.goBack();
        return true; // 阻止默认行为
      }
    );

    return () => backHandler.remove();
  }, [navigation]);

  return <View />;
}

相关技能

  • react-native-components: 为页面构建 UI 组件
  • react-native-platform: 平台特定的导航行为
  • react-native-performance: 优化导航性能