详情见React Navigation文档
基本使用
-
createStackNavigator();
是一个返回包含2个属性的对象的函数:Screen和Navigator。它们都是用于配置导航器的React组件。的元素Navigator应Screen作为其子元素来定义路由的配置。 -
Stack.Navigator
是一个需要进行路由配置的组件,因为它是其子级,并带有用于配置的其他道具并呈现我们的内容。 -
每个Stack.Screen组件都有一个
name
引用路径名称的componentprop
和一个指定要为该路由渲染的组件的prop
。这些是2个必备道具。 -
要指定堆栈中的初始路线是什么,请提供一个
initialRouteName
作为导航器的道具。
要指定特定于屏幕的选项,我们可以将options Prop
传递给Stack.Screen
,对于普通选项,我们可以传递screenOptions
给Stack.Navigator
function HomeScreen() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
</View>
);
};
const Stack = createStackNavigator();
<Stack.Navigator initialRouteName="Home">
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Details" component={DetailsScreen} />
</Stack.Navigator>
注意
:componentprop
接受组件,而不是渲染函数。不要传递内联函数(例如component={() => }),否则当父组件重新渲染时,您的组件将被卸载并重新安装,从而丢失所有状态。
页面切换
在按钮中添加事件,传入想跳转的名称navigation.navigate('name')
function DetailsScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Details Screen</Text>
<Button
title="Go to Details... again"
onPress={() => navigation.navigate('Details')}
/>
</View>
);
}
注意
: 当前页面跳转到当前页面,则不会跳转 ,但是要传递数据则将navigate
替换成push
将导航器状态替换为新状态:
navigation.reset({
index: 0,
routes: [{ name: 'Profile' }],
});
返回页面
除了页面上方的返回页面,你还能为按钮添加goBack()
<Button title="Go back" onPress={() => navigation.goBack()} />
返回第一个页面
<Button title="Go back" onPress={() => navigation.popToTop()} />
页面传值
-
将参数放入对象作为navigation.navigate函数的第二个参数,将参数传递给路线:
navigation.navigate('RouteName', { /* params go here */ })
-
获取参数:
route.params
。 -
注意
: 参数是JSON可序列化的
function HomeScreen({navigation} ) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
<Button
title="Go to Details"
onPress={() => {
navigation.navigate('Details', {
itemId: 86,
otherParam: 'anything you want here',
});
}}
/>
</View>
);
};
function DetailsScreen({route,navigation}) {
const { itemId } = route.params;
const { otherParam } = route.params;
<Text>itemId:{JSON.stringify(itemId)}</Text>
<Text>otherParam: {JSON.stringify(otherParam)}</Text>
}
可以使用 initialParams
为页面添加一个初始参数
<Stack.Screen
name="Details"
component={DetailsScreen}
initialParams={{ itemId: 42 }}
/>
更改路由参数
使用setParams
更改传递过来的数据
function ProfileScreen({route, navigation }) {
render() {
return (
<Button
onPress={() =>
navigation.setParams({
friends:
route.params.friends[0] === 'Brent'
? ['Wojciech', 'Szymon', 'Jakub']
: ['Brent', 'Satya', 'Michaś'],
title:
route.params.title === "Brent's Profile"
? "Lucy's Profile"
: "Brent's Profile",
})
}
title="Swap title and friends"
/>
);
}
}
配置标题栏
Screen
组件接受options
prop,prop是对象或返回对象的函数,其中包含各种配置选项。
<Stack.Navigator>
<Stack.Screen
name="Home"
component={HomeScreen}
options={{ title: 'My home' }}
/>
</Stack.Navigator>
标题使用参数
传递route
给options
<Stack.Screen
name="Profile"
component={HomeScreen}
options={({ route }) => ({ title: route.params.name })}
/>
更新options
使用setOptions
更新
<Button
title="Update the title"
onPress={() => navigation.setOptions({ title: 'Updated!' })}
/>
调整标题样式
headerStyle
:设置标题栏
headerTintColor
:设置标题和后退图标的颜色
headerTitleStyle
:自定义标题的样式
为所有页面添加样式:screenOptions
在Stack.Navigator
中添加
<Stack.Navigator
screenOptions={{
headerStyle: {
backgroundColor: '#f4511e',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
},
}}
>
自定义组件替换标题
function LogoTitle() {
return (
<Image
style={{ width: 50, height: 50 }}
source={require('@expo/snack-static/react-native-logo.png')}
/>
);
}
function StackScreen() {
return (
<Stack.Navigator>
<Stack.Screen
name="Home"
component={HomeScreen}
options={{ headerTitle: props => <LogoTitle {...props} /> }}
/>
</Stack.Navigator>
);
}
添加标题按钮
<Stack.Navigator>
<Stack.Screen
name="Home"
component={HomeScreen}
options={{
headerTitle: props => <LogoTitle {...props} />,
headerRight: () => (
<Button
onPress={() => alert('This is a button!')}
title="Info"
color="#fff"
/>
),
}}
/>
</Stack.Navigator>
自定义后退按钮和覆盖后退按钮
见官方文档
<NavigationContainer>
<Tab.Navigator
screenOptions={{
headerBackImage:() => (
<Text>hh</Text>
),
}}
嵌套导航
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={Home} />
</Stack.Navigator>
</NavigationContainer>
function Home() {
return (
<Tab.Navigator>
<Tab.Screen name="Feed" component={Feed} />
</Tab.Navigator>
);
}
function Feed() {
return (
<View>
<Text>Feed</Text>
</View>
);
}
注意
:
- 跳转嵌套的父页面时,会默认跳转到内部的初始页面
- 子页面中返回上一页,是上一页而不是父页面
- 导航动作由当前导航器处理,如果无法处理则冒泡
- 嵌套导航器不接收父项的事件
- 嵌套在内部的导航器中提供了特定于导航器的方法
解决嵌套子页面在父页面标题下
在父页面的Screen
的options
属性中添加headerShown: false
<RootStack.Screen name="AAA"
component={AAA}
options={{ headerShown: false }}
/>
在跳转中你可以传入screen来跳转到指定的子页面
navigation.navigate('Root', { screen: 'Settings' });
跳转指定页面并传参
navigation.navigate('Root', {
screen: 'Settings',
params: { user: 'jane' },
});
深层嵌套
下例中将导航到Media屏幕,该Sound屏幕位于嵌套在Settings屏幕内部的导航器中,位于嵌套在屏幕内部的导航器中。
navigation.navigate('Root', {
screen: 'Settings',
params: {
screen: 'Sound',
params: {
screen: 'Media',
},
},
});
常用样式:
作用 | 代码 | 位置 |
---|---|---|
页面左右切换 | cardStyleInterpolator:CardStyleInterpolators.forHorizontalIOS | screenOptions |
隐藏标题头部 | headerMode=“none” | Tab.Navigator |
自定义后退按钮 | headerBackImage:() => ( ) | options |
自定义头部标题 | headerTitle: props => <LogoTitle {…props} /> | options |
标题按钮 | headerRight: () => () | options |