传统的单页面应用,基于url的hash值进行路由跳转,hybrid App的跳转原理与此不同,其原理更像是web浏览器的前进后退。
React Navigation是RN官方提供的工具,它有三种导航方式:
Stack navigation:顶部导航条,用来跳转页面和传递参数
Tab navigation:底部标签栏,用来区分模块
Drawer navigation:抽屉,从App左侧滑出一个页面
stack navigation类似浏览器的导航处理,本文我们讨论的就是stack navigation方式。 当用户与它进行交互时,应用程序会从导航堆栈中新增和删除页面,这样就实现了不同页面的切换。
下面是我学习过程对官方文档的一个个人总结。
官方文档:React Navigation
插件安装
npm install react-navigation --save
npm install react-native-gesture-handler
最简单的实现一般包括以下几个步骤
使用createStackNavigator方法,该方法返回 React 组件。
import {createStackNavigator} from 'react-navigation';
import Main from '../Main';
import Page1 from '../Page1';
import Page2 from '../Page2';
export const Router = createStackNavigator({
Main: {screen: Main}, // routeName: {screen: component}
Page1: {screen: Page1},
Page2: {screen: Page2},
}
);
你可以将此文件直接写在App.js中,或者单独写一个文件,再在App.js中引用。我这里单独写成一个文件。
注意需要用AppContainer包裹整个环境。
App.js
import React, { Component } from 'react';
import { createAppContainer } from "react-navigation";
import {Router} from './src/navigator/Router';
const AppContainer = createAppContainer(Router);
export default class App extends Component {
render() {
return ;
}
}
定义好路由之后,调用this.props.navigation.navigate('Page1')方法实现跳转。
这里还有另一个方法this.props.navigation.push('Page1'),它与navigate()方法的区别是,如果从当前页跳转到当前页(比如我们复用组件,只是改变里面的某些参数),调用 navigate(),它不会做任何改变,push()方法则不考虑现有导航,直接添加路由,所以可以实现当前页到当前页的跳转。
返回上一页,用this.props.navigation.goBack()方法。
this.props.navigation.navigate('RouteName', yourParam)
读取数据:this.props.navigation.state.params。读取数据还可以用this.props.navigation.getParam('itemId', 'defaultValue'),这种方式,因为我们已经设置了一个default value,所以不必处理参数为空的情况。
修改当前页的参数:this.props.navigation.setParam ({otherParam: 'Updated!'})。
单个组件标题栏
通过配置navigationOptions实现自定义标题栏。
class HomeScreen extends React.Component {
static navigationOptions = {
title: 'Home',
headerStyle: {
backgroundColor: '#f4511e',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
},
};
/* render function, etc */
}
设置通用标题栏样式
上述方法是在单个页面中设置标题栏的方法,如果我们要为所有页面的header设置统一的样式,无需在每个页面中写重复的代码,在createStackNavigator配置defaultNavigationOptions即可。
export const Router = createStackNavigator({
Main: {screen: Main}, // routeName: {screen: component}
Page1: {screen: Page1},
Page2: {screen: Page2},
},
{
initialRouteName: 'Main', // 初始化加载的页面
defaultNavigationOptions: { // 设置统一的header样式
headerStyle: {
backgroundColor: '#f4511e',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
},
},
}
);
标题栏传值
注意navigation的引用方式
class DetailsScreen extends React.Component {
static navigationOptions = ({ navigation }) => {
return {
title: navigation.getParam('otherParam', 'A Nested Details Screen'),
};
};
/* render function, etc */
}
使用自定义组件替换标题栏
class LogoTitle extends React.Component {
render() {
return (
);
}
}
class HomeScreen extends React.Component {
static navigationOptions = {
// headerTitle instead of title
headerTitle: ,
};
/* render function, etc */
}
static navigationOptions = {
headerTitle: ,
headerRight: (