我们使用的是3.x版本,需要做如下操作
一.引入react-navigation
yarn add react-navigation
复制代码
但是作为过来人,告诉你肯定会报错,缺少这个warn当中的一个库react-native-gesture-handler所以也别走弯路,把这些库都给加上
#这是一个手势库
yarn add react-native-gesture-handler
#我也不知道用来干嘛的库,大概是一些屏幕设计吧,这是它的github:https://github.com/browniefed/react-native-screens
yarn add react-native-screens
#react-native-gesture-handler又依赖如下库
yarn add react-art
yarn add react-dom
yarn add react-native-web
复制代码
全都装完以后,link一下项目
react-native link
复制代码
这里注意了,在0.59中已经提到,不建议这样做,后续会移除这个命令,必须带上包名link才行
友情提示一下:三方库带原生的需要link,不带原生的没必要link
#xxxx为三方库名字
react-native link xxxx
复制代码
运行一下项目,可以正常运行,说明没有link错误,接下来我们分享一下这个三方库的基本使用
二.使用
常用的有三个API
API名 | 描述 |
---|---|
createAppContainer | 肯定会用到,这是对外暴露的顶级出口 |
createStackNavigator | 创建正常页面的navigation |
createBottomTabNavigator | 创建带tabbar的navigation |
createSwitchNavigator | 用于路由切割 |
先说我们的目的:创建一个登录页和两个业务的带tab的基础页面 效果如下
接下来在构建这样一个基础页面的过程中我逐步讲解
1.创建一个包含两个页面的基础路由
2.创建带tab的路由
我们需要创建一个带tab的路由,并把homeView和MyView放到这个tab里面
这里要声明一下,带tab的路由,有很多种创建方式,我这里写两种,一种是我推荐的,一种是react-navigation团队推荐的(但是我不推荐).
react-navigation推荐的方式(我找不到推荐的git地址了)
直接上代码
tab栈里面包含了12,其他所有页面需要写到1和2中 如图中,我在路由栈1和路由栈2中分别新增了1个页面H1和My1.
我们运行一下项目
可以发现如下问题:
- 1.二级页面仍然有底下的tabbar
从上述的gif可以看到,当我从一级页面HomeView跳转到二级页面H1,在H1的页面中,tabbar还存在.当然,这个问题是可以解决的.并且官网也提供了解决方案
- 2.路由层级"混乱",可能会引发非预期的后果
如gif,可以发现,我们从MyView跳转到H1,但是H1的返回却是返回到HomeView,可能会和我们的预期不同.
当然也是可以解决的,只需要将H1也放到路由栈2中即可.但这意味着可能一个页面你需要注册好几次路由栈,凭空添加了一些维护成本
我推荐的方式
第一次改写代码如图
回到上一个截图,我们可以看到,路由层级关系是
我们可以看到,root包含一个header,里面的路由栈1也包含一个header.
因此我们只需要去掉一个header即可,这里我们去掉root顶级的header,原因是tab中两个页面都是共享root的一个header,在视觉上这是不正确的
最终代码如下(没变的部分我就折叠起来了,不然一张图截不下):
我们再运行一下,效果如下
3.创建包含login页面的路由栈
创建一个新的js文件放此路由栈,如图
4.路由导出
由于最终要导出了,我们对前面的路由栈也做了一些小改动
包含tab的路由栈
包含导航的路由栈没有变化
创建做一个新的js文件导出最终的路由栈,如图
我们再使用createAppContainer将createSwitchNavigator包裹,得到最终的一个顶级路由,注意createAppContainer方法最终得到的是一个Commponent,可以直接当做组件应用
这时候,你直接导出AppTopNav是可以正常使用的
至于为什么我要额外做一个组件,请继续往后看4.构建不带props的API路由
最终效果:
3.常见使用方式
例如下面的Login页面,由于login本身页面是被createStackNavigator包裹的,navigation这个对象已经通过props传递了,使用如图
this.props.navigation.navigate("注册的页面名称","传递参数对象,可选项")
复制代码
4.构建不带props的API路由层
我们经常会有各种"切面"需求,举个例子:
无论当前在哪个页面,只要发现你的登录状态过期,立即跳回到登录页.
在代码层面看,你接受到"登录状态过期"这个信号的时候,你百分之八十的可能性是不在UI层的,可能在网络层其他层面,这时候你就会发现没有navigation给你用,就很难受.
复制代码
因此,我们需要构建一个存储顶级路由,只暴露API方法的路由层
我们可以新建一个js如下图
设置好了set方法和跳转方法,接下来就是怎么set顶级路由进去,回答我们?的问题
使用起来只需要:
NavigationService.navigate("注册的页面名称","传递参数对象,可选项")
复制代码