React Navigation之页面之间跳转、返回
BG
在React Native开发app中,使用React Navigation进行路由管理是官方推荐的方式。
React Native没有像Web浏览器那样的内置全局历史堆栈的概念 -- 这也是 React Navigation 存在的意义所在。
我们以最常见的导航器createStackNavigator
为例看一下页面之间的跳转方法有哪些:
一、navigation跳转场景总结:
跳转到某个页面的场景有以下几种:
如果我们堆栈中有A>B>C>D>D 5个路由,其中A是第一个页面。
场景一、A>B
this.props.navigation.navigate('B')
场景一:C>A,有两种方法:
(1).可以使用this.props.navigation.popToTop()
返回堆栈中的第一个页面。
(2).可以使用this.props.navigation.navigate(A)
返回堆栈中的A页面。
场景三、D>D
this.props.navigation.push('D')
场景四、D>C
直接this.props.navigation.goBack()
二、简单举例:
1.创建一个简单的stack navigator
createStackNavigator使用方法这里就不详细介绍啦。具体代码如下:
import React from 'react';
import { View, Button ,Text } from 'react-native';
import { createStackNavigator, createAppContainer } from 'react-navigation';
class HomeScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
<Button
title="Go to Details"
onPress={() => this.props.navigation.navigate('Details')}
/>
</View>
);
}
}
class DetailsScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Details Screen</Text>
</View>
);
}
}
const RootStack = createStackNavigator(
{
Home: HomeScreen,
Details: DetailsScreen,
},
{
initialRouteName: 'Home',
}
);
const AppContainer = createAppContainer(RootStack);
export default class App extends React.Component {
render() {
return <AppContainer />;
}
}
2.跳转到新页面:this.props.navigation.navigate
在Home页面使用this.props.navigation.navigate('Details')方法跳转到Details页面,这样就有了一个包含2个路由的堆栈:1) Home 路由 2) Details 路由。
-
this.props.navigation
:navigation
属性 传递给每个在 stack navigator 中定义的( 页面组件)。 -
navigate('Details')
:我们使用用户将要跳转的路由的名称(也就是key)来调用navigate
方法。
如果我们使用未在 stack navigator 中定义的路由名称调用this.props.navigation.navigate 方法,则不会发生任何事情。 换句话说,我们只能导航到已经在我们的 stack navigator 上定义的路由; 不能随便导航到任意组件。
3.多次导航到同一路由:navigate
orpush
我们已经有一个包含了2个路由的堆栈:1) Home 路由 2) Details 路由。 如果我们从 Detail 页面再次跳转到 Detail 路由将会发生什么?
class DetailsScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Details Screen</Text>
<Button
title="Go to Details... again"
onPress={() => this.props.navigation.navigate('Details')}
/>
</View>
);
}
}
如果你运行这个代码,你会注意到,当你点击“Go to Details... again”时,它什么也不做! 这是因为我们已经在 Details 路由上了。 导航功能粗略地意味着“去这个页面”,如果你已经在那个页面上,那么意味着它不会做任何事情。
如果你非要添加另一个 Details 页面。 (这也是非常常见的情况下, 你传递一些独特的数据到每个Details 页面),那么可以使用navigate push
:
<Button
title="Go to Details... again"
onPress={() => this.props.navigation.push('Details')}
/>
每次调用
push
时, 会向导航堆栈中添加新路由,也就是会再打开一个Details页面。
三、注意:
C>A是一个很常见需求,在堆栈深处跨越多个
页面返回。
你可能会问:在C页面中使用this.props.navigation.navigate(A)
为什么也能返回堆栈中的A页面呢?
答案:
this.props.navigation.navigate('RouteName')
方法的作用是:
(1).将新路由推送到堆栈导航器,如果它尚未在堆栈中,则跳转到该页面。
(2).如果它已经在堆栈中,则返回堆栈中的现有页面。