react-native组件生命周期在navigator上的表现(续)

前言:(依旧是啰嗦的初级内容),本来我以为之前的测试对Navigator的用法和生命周期已经比较明了了。后来因为某个原因我看了一下Navigator的代码实现,发现人家Navigator提供一大堆的跳转方法,不仅仅是push和pop……我竟然之前一直没想过它还有其他方法,只是隐隐觉得这2个方法是不是少了点,很多需求都不好实现。结果只是我知道太少而已(一看就是没写过完整应用的人)。下面就顺便说一下这些方法,再简单解释一下它们关联的页面的生命周期。

routestack数组

在介绍跳转方法之前,先简单说说Navigator实现页面跳转的原理。在其实现代码里面,有个贯通全局的routestack(路由栈)数组。这个数组里面保存了跳转的页面信息。接下来要介绍的一大堆方法,都是围绕它来实现的,比如push方法就是在原有基础上再加载一个页面,然后把这个新页面的信息给添加到数组的尾部。pop则是销毁当前的页面,同时在数组尾部把这个被销毁的页面的信息给去掉。这都属于典型的栈(stack)式数据结构用法,所以取名为routestack。

然后Navigator提供了一个方法,可以返回一个路由栈数组给我们,当然这个返回的数组的信息肯定没有内部实现的那么多,但也是很有用的。
方法:

1
getCurrentRoutes()

基于我上次的demo: github, 从第一个页面push到第二个页面,再push到第三个页面,在第三个页面上返回的路由栈数组长这样:

1
2
3
4
5
[
{ name: 'firstpage', component: [Function: Firstpage] },
{ name: 'secondpage', component: [Function: Secondpage], params: { info: 'from firstpage' } },
{ name: 'thirdpage', component: [Function: Thirdpage], params: { info: 'from secondpage' } }
]

pop方法们

关于push的方法只有一个,但pop类的方法除了pop本身以外,还有以下几个:

  • popToTop()
  • _popN(n)
  • popToRoute(route)
  • resetTo(route)

其实看名字都知道作用了,大概解释下。
另外如果解释有举例,都是基于这个假设:当前路由栈数组有[1,2,3]共3个页面(数组里面的123分别代表一个route对象,看懂意思就行),当前页为3号页面。

1
popToTop()  //直接回到第1个页面,其他页面全部销毁(组件unmount,生命到了尽头),例子中路由栈最后变成 [1]
1
_popN(n)  //n为数字,返回到前n层页面的意思。n为1,就和pop()方法是一样的,n不能大于当前路由栈数组的长度减一。 这是个内部方法,但感觉某些场景可能有用(比如想直接回退两层),但有风险,n出错程序就要崩。返回经过的那些页面也是全部unmount。
1
popToRoute(route)  //回到路由栈的route对象的那一页。但这个route对象不能像push那样直接写类似{ name: 'firstpage', component:Firstpage }这样的对象字面量,而是只能用 getCurrentRoutes()返回的数组里面去挑一个出来,也就是说只能用对象栈已有的route对象。
1
resetTo(route) //先咔嚓掉第一个页面,然后新建一个route指代的页面放在第一个页面的位置,再把其他剩余的页面全部干掉。比如我 resetTo(2),路由栈数组由[1,2,3]变成[2,2,3],最终变成[2]。这个其实严格说来不算pop方法,但他咔嚓的页面也不少,就暂时归pop一类好了。

replace家族

我之前嫌弃Navigator方法少的时候,就在嘀咕好歹给个replace的方法嘛,要不然某些应用场景还真没法实现。replace的方法有如下4个:

  • replace(route)
  • replacePrevious(route)
  • replacePreviousAndPop(route)
  • replaceAtIndex(route, index, cb)

他们的功能,主要是对当前路由栈的页面进行替换。

1
replace(route) //把当前页面给销毁掉,然后新建一个route指代的页面来代替当前页面,注意这个过程是没有过场动画效果的。比如我触发replace(2)方法,路由栈从[1,2,3]变成[1,2,2]。这个最常用的地方应该是自己替换自己(相当于重载页面)。
1
replacePrevious(route) //把上一页给销毁掉,新建route指代页面代替它,没动画,你只有pop回去的时候才会发现已经被改了。比如触发 replacePrevious(1),路由栈会从[1,2,3]变成[1,1,3]。
1
replacePreviousAndPop (route) //在前面方法的基础上,帮你pop回去……
1
replaceAtIndex(route, index, cb) //把index指的那一页给销毁,并用route指代的页面来代替。其实在Navigator的实现代码里面,上面2个方法就是用这个方法加工了一下。那个cb参数不知道有什么用,实现代码也没调用。

jump团伙

之前那些方法,都是伴随着页面组件的各种生老病死,仔细想想还是很残酷的,接下来的方法讲究以活为贵,不会打生打死,比较简单,我就名字和解释放一堆了。

1
jumpBack() //跳转上一页,当前页面组件不销毁,而且不会触发任何更新动作,与之对比,pop是销毁当前组件,且触发上一页的组件更新。比如路由栈[1,2,3],运行jumpBack(),页面跳到2号页面,但路由栈依然是[1,2,3],活动页面为2号。
1
jumpForward()//跳转后一页,前提是有后一页可以跳。比如之前运行了jumpBack(),再运行jumpForward(),就可以又从2号页面跳回3号页面,路由栈继续是[1,2,3]。
1
jumpTo(route)//跳转指定页面,这个route参数和之前那个 popToRoute是一样的,不能指定对象字面量,只能从当前路由栈里面取。