2017-09-08 20:37:08

React Native的路由演进

Navigator

在最初的时候,RN有一个安卓和IOS共用的路由组件:Navigator。该组件在v0.18被标记为废弃,并在v0.44倍删除。

无论从什么角度来看,这个组件都是RN的黑历史,作为一个路由库,它没有任何钩子存在,并且通篇都是使用push(Component)这种模式来控制路由。

也就是说,该路由库在执行路由操作时并不知道有什么路由存在,这导致很多优化没法做。另外,深度链接也是不可能有的。

实验性Navigator

这个路由是在Navigator组件被标记为废弃后进入RN官方维护的,然而直到被删除(甚至比Navigator先被删)都没有从实验性文件夹中移动出来过。

虽然如此,实验性Navigator的思想是本文介绍的几种路由库中最先进的:它的路由状态全部由Redux状态控制,你不使用Redux甚至都无法使用这个库。

在Navigator被标记为废弃之后,我曾经尝试过换用这个库,然而它有一个非常严重的问题:RN的手势系统会随时触发Redux操作,而这个库甚至没有关闭这个功能的开关。

虽然如此,之所以实验性Navigator会被废弃,我还是认为是因为它太过依赖Redux。

顺带喷一下Redux,读者认为是redux、redux-thunk、react-redux、redux-saga、reselect方案好呢还是mobx方案好呢?对于我来说,前者的功能加起来也就是另一个vuex而已。

react-navigation

从v0.44开始,react-navigation是官方指定唯一路由库。它使用了useNativeDriver参数来获得纯JS层面的60帧体验,而且因为路由的特殊性质,也不会触发Animated方法的bug。

react-navigation抽象出了三种路由,很好地满足了安卓上除了路由外的额外组件需求,并且做到了IOS兼容。在它的路由底层,可以通过router对象操作底层逻辑,例如保证push相同页面只会真正推入一个页面。

它也有高级功能,例如深度链接,以及实验性Navigator所具有的redux状态控制的特点,因此现在市面上超过一半的RN app都是使用这个路由库的。

然而,它的缺点也有很多:

  • 非原生
    • 之前页面有复杂操作时仍然会在过渡时掉帧
  • 没有细粒度钩子
    • 比如componentWillFocus、componentWillLeave
  • 更新较慢
    • 从v0.44至现在的v0.49,五个月过去了,它只发布了修改甚少的两个beta版本

有些缺点是纯JS很难解决的,因此接下来还有一个库。

react-native-navigation

虽然我在psnine中是用的react-navigation,但是必须得说,react-native-navigation才是RN最好的路由库。它完全由原生代码写成,并且保证了IOS和安卓的兼容,也支持平台独占的一些高级组件,例如安卓的collapseHeader和sharedElement。对于后者来说,非原生的react-navigation是一点实现可能都没有的。react-native-navigation还支持原生层面的组件路由钩子,基本保证了和网页端路由库功能相似。

说到缺点,react-native-navigation不支持redux控制,也不支持指定页面进行操作,也就是说,你在底层pop推出一个页面,会推出最顶层的那个页面。

幸运的是,v2版本正在解决这个问题。而且,v2版本是TDD的开发模式,用这个库的风险比用RN还小。依照目前的v2开发速度,目测今年年底能开发完毕。

另外,react-native-navigation干脆修改了RN的启动方式,它可以在异步操作(例如获得用户设置的参数)后再启动App,而在RN中这样的操作是会直接崩溃的。

本文链接:https://smallpath.me/post/react-native-router

-- EOF --