# react-navigation-demo
**Repository Path**: cyf2019/react-navigation-demo
## Basic Information
- **Project Name**: react-navigation-demo
- **Description**: No description available
- **Primary Language**: Unknown
- **License**: MIT
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2021-11-17
- **Last Updated**: 2021-11-17
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# react-navigation导航组件使用详解
**注意了,如果有小伙伴们发现运行作者提供的react-navigation示例项目报如下的错误,可能是大家使用了 `yarn install ` 命令,解决这个错误的办法就是将nodemodules删除,然后使用`npm install `命令来安装,最后使用 `npm start` 来起服务,应该就不报错了,如果还有报错,请加作者交流群,将问题反馈到群里,谢谢。**

# RN技术总结
* 作者React Native开源项目OneM地址(按照企业开发标准搭建框架完成开发的):**[https://github.com/guangqiang-liu/OneM](https://github.com/guangqiang-liu/OneM)** (欢迎小伙伴们 **star**)
* 作者简书主页:包含60多篇RN开发相关的技术文章[http://www.jianshu.com/u/023338566ca5](http://www.jianshu.com/u/023338566ca5) (欢迎小伙伴们:**多多关注**,**多多点赞**)
* 作者React Native QQ技术交流群:**620792950** 欢迎小伙伴进群交流学习
* 友情提示:**在开发中有遇到RN相关的技术问题,欢迎小伙伴加入交流群(620792950),在群里提问、互相交流学习。交流群也定期更新最新的RN学习资料给大家,谢谢支持!**
# 前言
> react-navigation 组件是官方推荐使用的导航组件,功能和性能都远远的优于之前的Navigator组件,公司的RN项目最早是使用的`react-native-router-flux`导航组件,因为那个时候`react-navigation` 组件还没有出来,在使用了`react-navigation`后,感觉比react-native-router-flux组件有更加强大的功能,体验也略好些,这两个导航组件是目前star最多的导航组件,并且他们都完美的支持与Redux框架的结合使用,推荐小伙伴们两个组件都尝试使用下。
# react-navigation官方地址
[react-navigation](https://github.com/react-community/react-navigation)
# react-navigation Demo地址
[https://github.com/guangqiang-liu/react-navigation-demo](https://github.com/guangqiang-liu/react-navigation-demo)
# react-navigation简书讲解地址
[http://www.jianshu.com/p/5c070a302192](http://www.jianshu.com/p/5c070a302192)
Demo示例讲解包含三部分
* react-navigation中最常用的基础用法讲解
* react-navigation中StackNavigator与TabNavigator和DrawerNavigator的混合嵌套使用
* react-navigation与Redux框架结合使用示例
# Demo效果图

**注意: 有小伙伴说Demo运行报错,这里大家需要注意,Demo clone下来之后,我们先要执行 `npm install` 操作, 然后在执行 `react-native link`,最后在 执行 `npm start` 来运行项目,如果还有其他的报错信息,欢迎进群提出报错信息**
# 对Redux用法不熟悉的同学们,请看作者的Redux入门讲解
[http://www.jianshu.com/p/faa98d8bd3fa](http://www.jianshu.com/p/faa98d8bd3fa)
# react-navigation 主要组成
react-navigation 组件主要由三大部分组成
* StackNavigator:类似于iOS中的UINavigationController,顶部的导航栏,主要用于页面间的跳转
* TabNavigator:类似于iOS中的UITabBarController,底部的tabBar选项卡,主要用于在同一tab下的不同页面的切换
* DrawerNavigator:类似于iOS中常用的抽屉功能,抽屉导航栏
下面我们对`react-navigation`详解也主要围绕这三个API来展开
# StackNavigator
StackNavigator导航栏的工作原理就和iOS中原生的UINavigationController一样的,是以栈的方式来管理每一个页面控制器的,当使用push就是入栈,当使用pop操作时就是出栈,这个很好理解,如果我们想让一个页面控制器有导航栏,那么我们首先要做的就是给这个页面注册导航
*API*
`StackNavigator(RouteConfigs, StackNavigatorConfig)`
StackNavigator函数中有两个参数:
* RouteConfigs
* StackNavigatorConfig
*配置RouteConfigs*
```
const RouteConfigs = {
Home: {
screen: TabBar // screen属性为必须配置属性
},
Home2: {
screen: Home2,
path:'app/Home2',
navigationOptions: {
title: '这是在RouteConfigs中设置的title',
headerTitleStyle: {
fontSize: 10
}
}
},
Home3: { screen: Home3 },
Home4: { screen: Home4 },
Home5: {screen: Home5},
Home6: {screen: Home6},
Home7: {screen: Home7},
Setting2: {screen: Setting2},
Setting3: {screen: Setting3},
}
```
*配置StackNavigatorConfig*
```
const StackNavigatorConfig = {
initialRouteName: 'Home',
initialRouteParams: {initPara: '初始页面参数'},
navigationOptions: {
title: '标题',
headerTitleStyle: {fontSize: 18, color: 'red'},
headerStyle: {height: 49},
},
paths: 'page/main',
mode: 'card',
headerMode: 'screen',
cardStyle: {backgroundColor: "#ffffff"},
transitionConfig: (() => ({
})),
onTransitionStart: (() => {
console.log('页面跳转动画开始')
}),
onTransitionEnd: (() => {
console.log('页面跳转动画结束')
}),
}
```
*注册导航*
```
import {StackNavigator, TabNavigator} from "react-navigation"
const Navigator = StackNavigator(RouteConfigs, StackNavigatorConfig)
export default class Main extends Component {
render() {
return (
)
}
}
```
从上面注册导航的代码块中,我们可以看出StackNavigator函数接受两个配置对象`RouteConfigs ` 和 `StackNavigatorConfig `,但是这里需要注意,第二个参数StackNavigatorConfig可以省略,表示不做任何导航默认配置
**StackNavigatorConfig配置参数**
* `initialRouteName `:导航器组件中初始显示页面的路由名称,如果不设置,则默认第一个路由页面为初始显示页面
* `initialRouteParams`:给初始路由的参数,在初始显示的页面中可以通过`this.props.navigation.state.params`来获取
* `navigationOptions`:路由页面的全局配置项
* `paths `:RouteConfigs里面路径设置的映射
* `mode `:页面跳转方式,有card和modal两种,默认为 card
* card:普通app常用的左右切换
* modal:只针对iOS平台,类似于iOS中的模态跳转,上下切换
* `headerMode `:页面跳转时,头部的动画模式,有 float 、 screen 、 none 三种
* float:渐变,类似iOS的原生效果,无透明,默认方式
* screen:标题与屏幕一起淡入淡出,如微信QQ的一样
* none:没有动画
* `cardStyle `:为各个页面设置统一的样式,比如背景色,字体大小等
* `transitionConfig `:配置页面跳转的动画,覆盖默认的动画效果
* `onTransitionStart `:页面跳转动画即将开始时调用
* `onTransitionEnd `:页面跳转动画一旦完成会马上调用
在StackNavigatorConfig配置参数中有一个`navigationOptions `属性的配置,这个配置项可以理解为导航栏的全局配置表,下面就讲解这个属性的可配置参数
**navigationOptions配置参数**
* `title `:导航栏的标题,或者Tab标题 tabBarLabel
* `header `:自定义的头部组件,使用该属性后系统的头部组件会消失,如果想在页面中自定义,可以设置为null,这样就不会出现页面中留有一个高度为64navigationBar的高度
* `headerTitle `:头部的标题,即页面的标题
* `headerBackTitle `:返回标题,默认为 title的标题
* `headerTruncatedBackTitle `:返回标题不能显示时(比如返回标题太长了)显示此标题,默认为'Back'
* `headerRight `:头部右边组件
* `headerLeft `:头部左边组件
* `headerStyle `:头部组件的样式
* `headerTitleStyle `:头部标题的样式
* `headerBackTitleStyle `:头部返回标题的样式
* `headerTintColor `:头部颜色
* `headerPressColorAndroid `:Android 5.0 以上MD风格的波纹颜色
* `gesturesEnabled `:否能侧滑返回,iOS 默认 true , Android 默认 false
**navigationOptions**
```
// StackNavigatorConfig中的navigationOptions属性也可以在组件内用static navigationOptions 设置(会覆盖此处的设置)
navigationOptions: {
header: { // 导航栏相关设置项
backTitle: '返回', // 左上角返回键文字
style: {
backgroundColor: '#fff'
},
titleStyle: {
color: 'green'
}
},
cardStack: {
gesturesEnabled: true
}
}
```
注意:
* 我们也可以在`RouteConfigs `中配置 navigationOptions属性,我们也可以在单独页面配置navigationOptions
* 在页面里面采用静态的方式配置 navigationOptions属性,会覆盖StackNavigator函数中`RouteConfigs `和`StackNavigatorConfig `对象中的navigationOptions属性里面的对应属性
* navigationOptions中属性的优先级是:页面中静态配置 > RouteConfigs > StackNavigatorConfig
*在`RouteConfigs `中配置 navigationOptions*
```
const RouteConfigs = {
Home: {
screen: TabBar
},
Home2: {
screen: Home2,
path:'app/Home2',
// 此处设置了, 会覆盖组件内的`static navigationOptions`设置. 具体参数详见下文
navigationOptions: {
title: '这是在RouteConfigs中设置的title',
headerTitleStyle: {
fontSize: 10
}
}
},
Home3: { screen: Home3 },
Home4: { screen: Home4 },
Home5: {screen: Home5},
Home6: {screen: Home6},
Home7: {screen: Home7},
Setting2: {screen: Setting2},
Setting3: {screen: Setting3},
}
```
*在具体页面中配置 navigationOptions*
```
import {StackNavigator, TabNavigator} from "react-navigation"
const Navigator = StackNavigator(RouteConfigs, StackNavigatorConfig)
export default class Main extends Component {
// 配置页面导航选项
static navigationOptions = {
title: 'homeThree',
header: (navigation, defaultHeader) => ({
...defaultHeader, // 默认预设
visible: true // 覆盖预设中的此项
}),
cardStack: {
gesturesEnabled: false // 是否可以右滑返回
}
}
// 或这样
static navigationOptions = {
// title: 'Two', // 固定标题
title: (navigation, childRouter) => { // 动态标题
if (navigation.state.params.isSelected) {
return `${navigation.state.params.name}选中`;
} else {
return `${navigation.state.params.name}没选中`;
}
},
header: ({ state, setParams, goBack }) => {
let right;
if (state.params.isSelected) {
right = (