安装
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 最值得利用的特性之一。