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