官方提供了两种导航器:Navigator和NavigatorIOS,后者只能在iOS平台使用,而前者是可以兼容Android和iOS平台的,详细介绍请参考官方介绍。

基本使用方式:

  • initialRoute:初始化路由,指定第一个页面
  • configureScene:配置页面切换场景
  • renderScene:渲染场景,返回需要显示的页面

常见的一个写法:

// ...
import FirstPage from './FirstPage';
class Demo10 extends Component {render() {return (<Navigatorstyle={{flex: 1}}initialRoute= {{id: 'FirstPage', component: FirstPage}}configureScene= {this.configureScene}renderScene= {this.renderScene}/>);}configureScene(route, routeStack) {if (route.sceneConfig) { // 有设置场景return route.sceneConfig;}return Navigator.SceneConfigs.PushFromRight; // 默认,右侧弹出}renderScene(route, navigator) {return <route.component {...route.passProps} navigator= {navigator}/>;}
}
// ...

initialRoute、configureScene、renderScene三个方法都和一个重要的参数route有关联。

route:表示路由对象的信息,我们看下它包含哪些参数

export interface Route {component?: React.ComponentClass<ViewProperties> // 必要参数,目标页面id?: string  // 通常用来设置一个与component匹配的标识title?: string // 常用来设置component页面的标题参数passProps?: Object; // 用来传递参数//anything else[key: string]: any//Commonly found propertiesbackButtonTitle?: string  // 标题栏左边按钮文字content?: stringmessage?: string;index?: numberonRightButtonPress?: () => void // 标题栏右边按钮点击事件rightButtonTitle?: string // 标题栏右边按钮文字sceneConfig?: SceneConfig // 切换场景的参数wrapperStyle?: any
}

本篇文章我们会使用到id、component、passProps、sceneConfig这四个参数,其他类似于backButtonTitle、onRightButtonPress等,这些参数在使用通用导航栏的时候会用到。

实际项目中,这种方式基本不会用,因为业务的复杂等原因会导致通用导航栏变得越来越臃肿,不可维护,如果想了解的同学,可以参考这篇文章。

Navigator和其他平台的导航一样,也是使用“栈”的形式来维护页面。我们都知道“栈”是先进后出的原则,Navigator多数API是“遵循”这个原则的。

不同的是,Navigator还提供了更加灵活的API,使得我们可以从类似“栈顶”跳转到“栈底”,同时还能保持“栈底”以上的页面存在而不销毁,我觉得可以用“伪栈”来形容它。

常用API

  • push(route) - 跳转到新的场景,并且将场景入栈,你可以稍后跳转过去
  • pop() - 跳转回去并且卸载掉当前场景
  • popToTop() - pop到栈中的第一个场景,卸载掉所有的其他场景。
  • popToRoute(route) - pop到路由指定的场景,在整个路由栈中,处于指定场景之后的场景将会被卸载。

  • jumpBack() - 跳回之前的路由,当然前提是保留现在的,还可以再跳回来,会给你保留原样。
  • jumpForward() - 上一个方法不是调到之前的路由了么,用这个跳回来就好了。
  • jumpTo(route) - 跳转到已有的场景并且不卸载。
    备注:与push&popxxx效果类似,只是不会卸载场景

  • replace(route) - 用一个新的路由替换掉当前场景
  • replaceAtIndex(route, index) - 替换掉指定序列的路由场景
  • replacePrevious(route) - 替换掉之前的场景
    备注:replacexxx:仅仅替换场景,并不会跳转

  • resetTo(route) - 跳转到新的场景,并且重置整个路由栈
  • immediatelyResetRouteStack(routeStack) - 用新的路由数组来重置路由栈
  • getCurrentRoutes() - 获取当前栈里的路由,也就是push进来,没有pop掉的那些。

为了演示以上API的使用,我们新建三个js文件,FirstPage.jsSecondPage.jsThirdPage.js

FirstPage作为导航控制器的根页面,请参考文章开头给出的代码示例。

push&popxxx:

1、FirstPage->push->SecondPage:传递参数from

// FirstPage.js
_push()
{this.props.navigator.push({id: 'SecondPage',component: SecondPage,passProps: {from: 'First Page'},sceneConfig: Navigator.SceneConfigs.HorizontalSwipeJump});
}

2、SecondPage->push->ThirdPage,代码类似就不贴了。然后,ThirdPage->pop->SecondPage,返回上一个页面

// ThirdPage.js
_pop()
{this.props.navigator.pop();
}

3、ThirdPage->popToTop->FirstPage,返回第一个页面

// ThirdPage.js
_popToTop() {this.props.navigator.popToTop();
}

4、ThirdPage->popToRoute->FirstPage,返回第一个页面

// ThirdPage.js
_popToRouteById(id) {var destRoute;this.props.navigator.getCurrentRoutes().map((route, i) => {if (route.id === id) {destRoute = route;}});// 携带参数destRoute.passProps = {from: 'Third Page'};this.props.navigator.popToRoute(destRoute);
}

效果图如下:

push&popxxx.gif

jumpxxx:

1、SecondPage->jumpBack->FirstPage:返回上一个场景,并且不卸载当前场景

// SecondPage.js
_jumpBack() {this.props.navigator.jumpBack();
}

2、FirstPage->jumpForward->SecondPage:与jumpBack配套使用,返回触发jumpBack的场景

// FirstPage.js
_jumpForward()
{this.props.navigator.jumpForward();
}

效果图如下:

jumpxxx.gif

我们打印下FirstPageSecondPage的生命周期函数componentDidMountcomponentWillUnmount

// FirstPage.js
componentDidMount() {console.log("FirstPage: componentDidMount");
}componentWillUnmount() {console.log("FirstPage: componentWillUnmount");
}// SecondPage.js
componentDidMount() {console.log("SecondPage: componentDidMount");
}componentWillUnmount() {console.log("SecondPage: componentWillUnmount");
}

lifecircle.png

我们看到,在来回的跳转过程中SecondPage并没有被卸载。

更有趣的是,从SecondPage jumpBack之后。在FirstPage页面,如果点击push,你会发现旧的SecondPage会被卸载,然后会创建一个新的SecondPage。console如下:

lifecircle2.png

3、SecondPage->jumpTo->FirstPage:跳转到一个已存在的场景,并且不卸载当前场景

// SecondPage.js
_jumpToById(id) {var destRoute;this.props.navigator.getCurrentRoutes().map((route, i) => {if (route.id === id) {destRoute = route;}});// 携带参数destRoute.passProps = {from: 'Second Page'};this.props.navigator.jumpTo(destRoute);
}

replacexxx:

新建一个场景FourthPage.js。当前“栈”里面的场景为FirstPage->SecondPage->ThirdPage
1、ThirdPage ->replacePrevious:在ThirdPage页面替换上一个场景(也就是SecondPage)为FourthPage

// ThirdPage.js
_replacePrevious()
{this.props.navigator.replacePrevious({id: 'FourthPage',component: FourthPage,});
}

此时,“栈”里面的场景为FirstPage->FourthPage->ThirdPage

2、replace(route)replaceAtIndex(route, index)replacePrevious非常类似,只是替换的场景不同而已,这里不做讲解,大家自己测试一下就知道效果了。

  • replace(route) - 用一个新的路由替换掉当前场景
  • replaceAtIndex(route, index) - 替换掉指定序列的路由场景

需要注意的是,replacexxx:仅仅替换场景,并不会跳转。

resetTo:

跳转到新的场景,并且重置整个路由栈。

想象这样一个场景,我们有个App,用户登录之后,可能已经进入三级页面,此时用户希望切换用户重新登录,这时候我们就需要跳转到登录页面,并且清空其他所有页面。

此时,就需要使用到resetTo。

我们在ThirdPage->resetTo->FourthPage,然后在FourthPage使用pop,看下是否还有其他页面存在。

// ThirdPage.js
_resetTo()
{this.props.navigator.resetTo({id: 'FourthPage',component: FourthPage,});
}
// FourthPage.js
_pop()
{this.props.navigator.pop();
}

效果图如下:

resetTo

我们看到整个路由“栈”被重新初始化,FourthPage成为“栈”的根页面。

immediatelyResetRouteStack(routeStack):

用新的路由数组来重置路由栈,与resetTo类似,只不过resetTo参数为一个对象,而immediatelyResetRouteStack(routeStack)为一个数组,感兴趣的同学可以自己尝试一下效果。

本文的源码地址:Demo10

[React Native]导航器Navigator相关推荐

  1. React Native的Navigator详解

    欢迎Follow我的Github,博客会同步在Github的Blog仓库更新.也可以关注我的CSDN博客的React Native分类 Github地址:LeoMobileDeveloper 前言 除 ...

  2. iOS开发者React Native学习路线

    2019独角兽企业重金招聘Python工程师标准>>> http://blog.talisk.cn/blog/2016/08/13/RN-Learning-path-for-iOS- ...

  3. React Native开发之动画(Animations)

    博主这个系列的文章 React Native开发之IDE(Atom+Nuclide) React Native开发之FlexBox代码+图解 React Native的Navigator详解 另外,我 ...

  4. [react native] navigator过渡卡顿问题

    为什么80%的码农都做不了架构师?>>>    navigator过渡卡顿问题 ReactNative导航设计与实现 https://segmentfault.com/a/11900 ...

  5. 【稀饭】react native 实战系列教程之Navigator实现页面跳转

    主界面开发 上一节,我们已经完成了首页的开发,现在,我们继续完成主界面的开发,就是添加底部'首页'和'我的'两个tabbar. 在js/文件夹下,新建MainScene.js文件 import Rea ...

  6. React Native——react-navigation的使用

    在 React Native 中,官方已经推荐使用 react-navigation 来实现各个界面的跳转和不同板块的切换. react-navigation 主要包括三个组件: StackNavig ...

  7. 如何使用React Native构建嵌套的抽屉菜单

    by Dhruvdutt Jadhav 由Dhruvdutt Jadhav 如何使用React Native构建嵌套的抽屉菜单 (How to build a nested drawer menu w ...

  8. 如何在React Native中构建项目并管理静态资源

    by Khoa Pham 通过Khoa Pham 如何在React Native中构建项目并管理静态资源 (How to structure your project and manage stati ...

  9. React Native移动框架功能研究

    React Native移动框架功能研究 此篇只研究React Native框架的功能. 一.React Natvie是什么 React Native是使用React(或者说JS)来开发原生APP的框 ...

  10. React Native 二 常用组件与开源组件

    2019独角兽企业重金招聘Python工程师标准>>> #0.手把手教React Native实战之开山篇##作者简介东方耀 Android开发RN技术 facebookgithub ...

最新文章

  1. Denoising DNA deep sequencing data—high-throughput sequencing errors and their correction
  2. Tri-Party Deep Network Representation
  3. c语言excel转pdf,基于C语言和Excel软件下光速测量仪测量玻璃折射率.pdf
  4. 【VS开发】【DSP开发】地址对齐
  5. 最新影视小程序源码去授权版免费下载
  6. 华为网络工程师认证有哪些?值不值得考?
  7. SWAN之ikev2协议crl-revoked配置测试
  8. 免费的mysql云平台_免费的mysql云服务器
  9. 项目开发遇到前端传递时间问题处理
  10. SpringBoot项目中增加favicon.ico图标
  11. 百度网盘批量重命名文件免费脚本---2020.07
  12. 地图之间经纬度转换靠谱吗
  13. android获取包名的几种方法
  14. 使用Tushare进行金融时间序列分析研究
  15. java调用执行windows命令
  16. 女生学计算机好吗有辐射,电脑辐射对女人有害吗
  17. 求职清单!AI商业落地企业Top100;『数据科学:理论、模型、算法与分析』电子书;超快多线程DataFrame 8K★;前沿论文 | ShowMeAI资讯日报
  18. 晚上睡眠质量不好怎么办?试试这些助眠方法,让你一招入睡
  19. 什么是无头浏览器?如何使用Golang实现无头浏览器截图?
  20. 网页图片实现百叶窗效果

热门文章

  1. VS2019 后面有“::”的名称一定是类名或命名空间名 解决办法汇总
  2. 快速排序的时间复杂度和空间复杂度
  3. 装饰器模式Decorate
  4. HDLC协议的基本概念和帧
  5. UVA 12307 Smallest Enclosing Rectangle(旋转卡壳)
  6. 360度评估前HR必须掌握的优劣势
  7. 一段话加省略号怎么写html,HTML 应用 文字省略号的表示
  8. js实现软键盘(兼容所有浏览器)
  9. 什么是数字孪生?把这篇文章看完你就能秒懂
  10. 百度面试题:求绝对值最小的数