我的GitHub
0%

React-Native 分享二之React-Navigation

我们使用的是3.x版本,需要做如下操作

一.引入react-navigation

1
yarn add react-navigation

如图
如图,我们发现有很多warn,报的是一些依赖没满足,一般我们说程序员不看warn,肯定就直接运行了.

但是作为过来人,告诉你肯定会报错,缺少这个warn当中的一个库react-native-gesture-handler所以也别走弯路,把这些库都给加上

1
2
3
4
5
6
7
8
9
#这是一个手势库
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一下项目

1
react-native link

link警告

这里注意了,在0.59中已经提到,不建议这样做,后续会移除这个命令,必须带上包名link才行

友情提示一下:三方库带原生的需要link,不带原生的没必要link

1
2
#xxxx为三方库名字
react-native link 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文件放此路由栈,如图
Login路由栈

4.路由导出

由于最终要导出了,我们对前面的路由栈也做了一些小改动

包含tab的路由栈
AppNav

包含导航的路由栈没有变化

创建做一个新的js文件导出最终的路由栈,如图

最终路由栈
我们可以看到,我们使用createSwitchNavigator这个API切割了两个路由栈,且第二个参数配置项中默认路由是AppLogin,这样默认就进入首页这个路由栈

我们再使用createAppContainer将createSwitchNavigator包裹,得到最终的一个顶级路由,注意createAppContainer方法最终得到的是一个Commponent,可以直接当做组件应用

这时候,你直接导出AppTopNav是可以正常使用的

至于为什么我要额外做一个组件,请继续往后看4.构建不带props的API路由

最终效果:
最终效果

3.常见使用方式

例如下面的Login页面,由于login本身页面是被createStackNavigator包裹的,navigation这个对象已经通过props传递了,使用如图

1
this.props.navigation.navigate("注册的页面名称","传递参数对象,可选项")

Login

4.构建不带props的API路由层

我们经常会有各种”切面”需求,举个例子:

1
2
3
无论当前在哪个页面,只要发现你的登录状态过期,立即跳回到登录页.

在代码层面看,你接受到"登录状态过期"这个信号的时候,你百分之八十的可能性是不在UI层的,可能在网络层其他层面,这时候你就会发现没有navigation给你用,就很难受.

因此,我们需要构建一个存储顶级路由,只暴露API方法的路由层

我们可以新建一个js如下图
NavigationService

设置好了set方法和跳转方法,接下来就是怎么set顶级路由进去,回答我们👆的问题

设置
我们可以在这里通过ref的方式获取这个顶级路由,并用于后续跳转

使用起来只需要:

1
NavigationService.navigate("注册的页面名称","传递参数对象,可选项")

如图
路由构造搭建到此完毕

demo地址

我是阿星,阿星的阿,阿星的星!