React Navigation基础 #
概述 #
React Navigation 是 React Native 社区最流行的导航解决方案。它提供了多种导航器类型,可以满足各种应用场景的导航需求。
安装 #
安装核心包 #
bash
npm install @react-navigation/native
安装依赖 #
bash
npm install react-native-screens react-native-safe-area-context
安装导航器 #
bash
npm install @react-navigation/native-stack
npm install @react-navigation/bottom-tabs
npm install @react-navigation/drawer
iOS 配置 #
bash
cd ios && pod install
基本配置 #
NavigationContainer #
在应用根组件包裹 NavigationContainer:
tsx
import React from 'react';
import {NavigationContainer} from '@react-navigation/native';
import {createNativeStackNavigator} from '@react-navigation/native-stack';
import HomeScreen from './screens/HomeScreen';
import DetailsScreen from './screens/DetailsScreen';
const Stack = createNativeStackNavigator();
const App = () => {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Details" component={DetailsScreen} />
</Stack.Navigator>
</NavigationContainer>
);
};
export default App;
Stack 导航 #
Stack 导航是最常用的导航方式,页面以堆栈形式管理。
基本使用 #
tsx
import React from 'react';
import {View, Text, Button, StyleSheet} from 'react-native';
import {NativeStackScreenProps} from '@react-navigation/native-stack';
type RootStackParamList = {
Home: undefined;
Details: {itemId: string; title: string};
Profile: {userId: string};
};
type Props = NativeStackScreenProps<RootStackParamList, 'Home'>;
const HomeScreen: React.FC<Props> = ({navigation}) => {
return (
<View style={styles.container}>
<Text style={styles.title}>Home Screen</Text>
<Button
title="Go to Details"
onPress={() => navigation.navigate('Details', {itemId: '42', title: 'My Item'})}
/>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
title: {
fontSize: 24,
fontWeight: 'bold',
},
});
export default HomeScreen;
接收参数 #
tsx
import React from 'react';
import {View, Text, Button, StyleSheet} from 'react-native';
import {NativeStackScreenProps} from '@react-navigation/native-stack';
type RootStackParamList = {
Details: {itemId: string; title: string};
};
type Props = NativeStackScreenProps<RootStackParamList, 'Details'>;
const DetailsScreen: React.FC<Props> = ({route, navigation}) => {
const {itemId, title} = route.params;
return (
<View style={styles.container}>
<Text style={styles.title}>{title}</Text>
<Text>Item ID: {itemId}</Text>
<Button title="Go back" onPress={() => navigation.goBack()} />
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
title: {
fontSize: 24,
fontWeight: 'bold',
},
});
export default DetailsScreen;
导航方法 #
tsx
const NavigationMethods = ({navigation}) => {
return (
<View>
{}
<Button title="Navigate" onPress={() => navigation.navigate('Details')} />
{}
<Button title="Push" onPress={() => navigation.push('Details')} />
{}
<Button title="Go Back" onPress={() => navigation.goBack()} />
{}
<Button title="Pop to Top" onPress={() => navigation.popToTop()} />
{}
<Button title="Replace" onPress={() => navigation.replace('Details')} />
{}
<Button
title="Reset"
onPress={() =>
navigation.reset({
index: 0,
routes: [{name: 'Home'}],
})
}
/>
</View>
);
};
配置标题栏 #
tsx
const Stack = createNativeStackNavigator();
const App = () => {
return (
<NavigationContainer>
<Stack.Navigator
initialRouteName="Home"
screenOptions={{
headerStyle: {
backgroundColor: '#007AFF',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
},
}}>
<Stack.Screen
name="Home"
component={HomeScreen}
options={{
title: '首页',
headerRight: () => (
<Button onPress={() => console.log('Info')} title="Info" color="#fff" />
),
}}
/>
<Stack.Screen
name="Details"
component={DetailsScreen}
options={({route}) => ({title: route.params.title})}
/>
</Stack.Navigator>
</NavigationContainer>
);
};
动态设置标题 #
tsx
import React, {useLayoutEffect} from 'react';
import {View, Text, Button} from 'react-native';
const DetailsScreen = ({navigation, route}) => {
const {title} = route.params;
useLayoutEffect(() => {
navigation.setOptions({
title: title,
headerRight: () => (
<Button title="Share" onPress={() => console.log('Share')} />
),
});
}, [navigation, title]);
return (
<View>
<Text>Details Screen</Text>
</View>
);
};
Tab 导航 #
Tab 导航用于底部标签栏导航。
基本使用 #
tsx
import React from 'react';
import {View, Text, StyleSheet} from 'react-native';
import {NavigationContainer} from '@react-navigation/native';
import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
import Icon from 'react-native-vector-icons/Ionicons';
const Tab = createBottomTabNavigator();
const HomeScreen = () => (
<View style={styles.container}>
<Text>Home Screen</Text>
</View>
);
const SettingsScreen = () => (
<View style={styles.container}>
<Text>Settings Screen</Text>
</View>
);
const App = () => {
return (
<NavigationContainer>
<Tab.Navigator
screenOptions={({route}) => ({
tabBarIcon: ({focused, color, size}) => {
let iconName: string;
if (route.name === 'Home') {
iconName = focused ? 'home' : 'home-outline';
} else if (route.name === 'Settings') {
iconName = focused ? 'settings' : 'settings-outline';
}
return <Icon name={iconName} size={size} color={color} />;
},
tabBarActiveTintColor: '#007AFF',
tabBarInactiveTintColor: 'gray',
})}>
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="Settings" component={SettingsScreen} />
</Tab.Navigator>
</NavigationContainer>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
});
export default App;
Tab 配置选项 #
tsx
<Tab.Navigator
screenOptions={{
tabBarActiveTintColor: '#007AFF',
tabBarInactiveTintColor: '#999',
tabBarStyle: {
backgroundColor: '#fff',
borderTopWidth: 1,
borderTopColor: '#eee',
},
tabBarLabelStyle: {
fontSize: 12,
fontWeight: '600',
},
}}>
<Tab.Screen
name="Home"
component={HomeScreen}
options={{
tabBarLabel: '首页',
tabBarBadge: 3,
}}
/>
<Tab.Screen
name="Profile"
component={ProfileScreen}
options={{
tabBarLabel: '我的',
}}
/>
</Tab.Navigator>
Drawer 导航 #
Drawer 导航用于侧边抽屉菜单。
基本使用 #
tsx
import React from 'react';
import {View, Text, Button, StyleSheet} from 'react-native';
import {NavigationContainer} from '@react-navigation/native';
import {createDrawerNavigator} from '@react-navigation/drawer';
const Drawer = createDrawerNavigator();
const HomeScreen = ({navigation}) => (
<View style={styles.container}>
<Text>Home Screen</Text>
<Button title="Open Drawer" onPress={() => navigation.openDrawer()} />
</View>
);
const NotificationsScreen = () => (
<View style={styles.container}>
<Text>Notifications Screen</Text>
</View>
);
const App = () => {
return (
<NavigationContainer>
<Drawer.Navigator
initialRouteName="Home"
screenOptions={{
drawerStyle: {
backgroundColor: '#fff',
width: 240,
},
drawerActiveTintColor: '#007AFF',
}}>
<Drawer.Screen name="Home" component={HomeScreen} />
<Drawer.Screen name="Notifications" component={NotificationsScreen} />
</Drawer.Navigator>
</NavigationContainer>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
});
export default App;
自定义抽屉内容 #
tsx
import React from 'react';
import {View, Text, TouchableOpacity, StyleSheet} from 'react-native';
import {DrawerContentScrollView, DrawerItem} from '@react-navigation/drawer';
const CustomDrawerContent = (props) => {
return (
<DrawerContentScrollView {...props}>
<View style={styles.header}>
<Text style={styles.userName}>John Doe</Text>
<Text style={styles.email}>john@example.com</Text>
</View>
<DrawerItem
label="Home"
onPress={() => props.navigation.navigate('Home')}
/>
<DrawerItem
label="Profile"
onPress={() => props.navigation.navigate('Profile')}
/>
<DrawerItem
label="Settings"
onPress={() => props.navigation.navigate('Settings')}
/>
<View style={styles.footer}>
<DrawerItem
label="Logout"
onPress={() => console.log('Logout')}
/>
</View>
</DrawerContentScrollView>
);
};
const styles = StyleSheet.create({
header: {
padding: 20,
borderBottomWidth: 1,
borderBottomColor: '#eee',
},
userName: {
fontSize: 18,
fontWeight: 'bold',
},
email: {
fontSize: 14,
color: '#666',
marginTop: 4,
},
footer: {
marginTop: 'auto',
borderTopWidth: 1,
borderTopColor: '#eee',
},
});
组合导航 #
将多种导航器组合使用:
tsx
import React from 'react';
import {NavigationContainer} from '@react-navigation/native';
import {createNativeStackNavigator} from '@react-navigation/native-stack';
import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
const Stack = createNativeStackNavigator();
const Tab = createBottomTabNavigator();
const HomeStack = () => (
<Stack.Navigator>
<Stack.Screen name="HomeList" component={HomeListScreen} />
<Stack.Screen name="HomeDetail" component={HomeDetailScreen} />
</Stack.Navigator>
);
const ProfileStack = () => (
<Stack.Navigator>
<Stack.Screen name="ProfileMain" component={ProfileScreen} />
<Stack.Screen name="EditProfile" component={EditProfileScreen} />
</Stack.Navigator>
);
const App = () => {
return (
<NavigationContainer>
<Tab.Navigator>
<Tab.Screen
name="HomeTab"
component={HomeStack}
options={{headerShown: false, tabBarLabel: '首页'}}
/>
<Tab.Screen
name="ProfileTab"
component={ProfileStack}
options={{headerShown: false, tabBarLabel: '我的'}}
/>
</Tab.Navigator>
</NavigationContainer>
);
};
导航状态管理 #
useNavigation Hook #
tsx
import React from 'react';
import {Button} from 'react-native';
import {useNavigation} from '@react-navigation/native';
const MyComponent = () => {
const navigation = useNavigation();
return (
<Button
title="Go to Details"
onPress={() => navigation.navigate('Details')}
/>
);
};
useRoute Hook #
tsx
import React from 'react';
import {Text} from 'react-native';
import {useRoute} from '@react-navigation/native';
const MyComponent = () => {
const route = useRoute();
const {itemId} = route.params;
return <Text>Item ID: {itemId}</Text>;
};
useFocusEffect #
页面获得焦点时执行:
tsx
import React from 'react';
import {useFocusEffect} from '@react-navigation/native';
const ProfileScreen = () => {
useFocusEffect(
React.useCallback(() => {
console.log('Screen focused');
return () => {
console.log('Screen unfocused');
};
}, []),
);
return <Text>Profile Screen</Text>;
};
总结 #
React Navigation 是 React Native 的标准导航解决方案:
- Stack 导航:页面堆栈管理
- Tab 导航:底部标签栏
- Drawer 导航:侧边抽屉菜单
- 组合导航:多种导航器组合使用
掌握这些导航方式,可以构建复杂的应用导航结构。
继续学习 导航进阶,了解导航参数传递、深层链接等高级功能。
最后更新:2026-03-28