React Navigation实现界面导航与跳转

Stella981
• 阅读 1330

React Native--使用React Navigation实现界面导航与跳转

2018年04月26日 20:59:24 theVicTory 阅读数 12068

        在浏览器中我们可以通过标签与url实现不同页面之间的跳转,利用浏览器的返回按钮返回之前浏览的页面,但是在React Native中却没有集成内嵌的全局栈来实现这个界面的跳转,因此需要使用第三方库来实现这个功能。React Navigation就是这样一个源于ReactNative社区的用于实现界面导航的js库。通过如下方法安装react navigation到你的项目中:

yarn add react-navigation
# 或者通过npm安装:
# npm install --save react-navigation

        React Navigation常用有三个组件,其中StackNavigator用于实现页面跳转,TabNavigation用于标签页之间切换,DrawerNavigation用于实现抽屉式侧边栏。使用前需要先引入组件:

import {DrawerNavigator,TabNavigator,StackNavigator} from 'react-navigation'

1、StackNavigator

        StackNavigator组件用于实现在不同的页面之间的跳转,并且对页面历史进行管理,就像浏览器那样,用一个栈保存浏览页面。当你打开一个新页面时,将页面压入栈顶,当你需要返回时,从栈顶弹出页面。不同的是,通过React Navigation可以在移动设备上获得更加真实的用户体验,比如利用屏幕手势操作,以及更加逼真的动画切换效果。

React Navigation实现界面导航与跳转

1.1、定义路由

        总体上看StackNavigator()接收两个参数,分别是需要跳转管理的路由模块以及Navigator的基本设置,返回一个React Component组件。因此可以将你的所有页面作为路由模块放在StackNavigator中形成根路由RootStack,然后将其作为ReactNative的入口导出。

        在每个路由模块中通过screen关键字定义对应渲染的ReactNative组件

const RootStack = StackNavigator(
  {//定义路由
Home: {                       //定义Home对应HomeScreen组件
screen: HomeScreen,
},
Details: {
      screen: DetailsScreen,
},
},
{//定义配置
initialRouteName: 'Home',     //设置初始路由为Home
}
);
export default class App extends Component {
  render() {                            //将Navigation作为根路径导出
return <RootStack />;
}
}

        嵌套路由:由于StackNavigator返回一个React组件,因此它也可以作为子组件添加到另一个StackNavigator路由中,形成层叠路由结构。例如Home Screen与DetailScreen构成MainStack,MainStack与ModalScreen构成RootStack:

React Navigation实现界面导航与跳转       React Navigation实现界面导航与跳转

1.2、路由跳转

        StackNavigator会为每个注册的路由组件传递参数navigation属性,通过this.props.navigation的navigate方法可以实现页面间的跳转,其参数为StackNavigator中已定义的路由,例如从主页跳转到详情页Details:

<Button title='跳转到详情' onPress={()=>this.props.navigation.navigate('Details')} />

        返回:每个界面的头部导航栏左边默认设置了一个返回按钮,通过它可以返回到之前一个页面,如果你希望手动触发返回,可以调用this.props.navigation.goBack()。

        路由跳转实际上就是新打开一个页面并将路由压入一个栈中,点击返回时,从栈顶弹出一个页面。与浏览器不同的是,当给navigate传递的参数是本页面时,它依旧会压入栈内,点击返回时会弹出本页面,而浏览器会辨别这是本页面,不会再压入栈顶。

1.3、参数传递

        当页面跳转时,可以把需要传递的数据作为参数放在navigate方法的第二个参数中,例如:

<Button title='跳转到详情'
onPress={()=>this.props.navigation.navigate('Details',{
          userName:'Tory',
userInfo:'Hello'
})}
/>

        在路由页面内,通过 this.props.navigation.state.params可以得到上一个页面传入的参数,例如在Details页面获取上面的数据:

class DetailsScreen extends Component {
  render() {
    const data=this.props.navigation.state.params;
return (
      <View style={styles.container}>
        <Text>你好,{data.userName}!</Text>
      </View>
);
}
}

1.4、导航栏设置

       通过对组件内的静态常量 navigationOptions可以对组件的导航栏进行设置。

1.4.1、设置与修改

        静态对象:navigationOptions可以直接接收一个对象,例如设置详情页导航栏的标题

class DetailsScreen extends Component {
  static navigationOptions = {
    title: '详情页'
};
}

     函数返回:由于上面通过static设置的静态常量,它不是组件的一个实例,无法通过this.props访问到navigation.state.params。但如果通过函数的方式返回navigationOptions对象,React Navigation在调用函数时会函数默认传入参数props,就可以拿到params。例如:

static navigationOptions=((props)=>{
  return {
    title:props.navigation.state.params.title
  }
});

        修改navigationOptions:通过this.props.navigation.setParams()方法可以对params进行修改,例如修改标题:

<Button title='修改标题'
onPress={()=>{
          this.props.navigation.setParams({title:'修改后的标题'})
        }}
/>
1.4.2、navigationOptions属性
static navigationOptions={
  title:'详情页',
header:HeaderComponent,                       //自定义头部组件
headerTitle:TitleComponent,                   //自定义标题组件
headerLeft:LeftComponent,                     //自定义左边组件,会替换掉默认返回按钮
headerRight:<Text>右边元素</Text>,            //自定义右边元素,注意这里不可以放组件
headerBackImage:{uri:'mipmap/ic_launcher'},   //自定义返回按钮的图片
headerStyle:{                                 //导航栏样式设置
backgroundColor:'#8bc9ff',
},
headerTintColor:'#fff',                       //按钮、标题颜色设置
headerTitleStyle:{                            //标题字体样式设置
fontWeight:'bold',
},
headerTransparent:true,                       //使头部背景透明
gesturesEnabled:true,                         //开启手势操作
gestureDirection:'inverted',            //修改返回手势操作方向为从右到左,默认为从左到右
gestureResponseDistance:{               //定义手势响应距离屏幕边界的距离
horizontal:100,
vertical:50
}
};

       如果在组件内部定义navigationOptions,它只会对当前页面起作用,如果希望对所有组件设置通用options,可以把navigationOptions对象放在前面的1.1提到的路由定义中。页面内的navigationOptions比通用设置具有更高的优先级。

        注意自定义组件返回的是JSX元素,而不是React Component类。

const RootStack = StackNavigator(
  {//定义路由
Home: {screen: HomeScreen},
Details:{screen: DetailsScreen},
},
{//定义配置
initialRouteName: 'Home',     navigationOptions:{           //导航栏通用设置
headerStyle:{
        backgroundColor:'#7276ff'
}
    }
  }
);

1.5、头部与组件通信

        在navigationOptions中设置的组件无法通过this访问到页面组件DetailsScreen,如果希望二者之间进行通信,则需要借助navigation.params。例如:

class DetailsScreen extends React.Component {
  state={count:0};
static navigationOptions = (props) => {
    const params = props.navigation.state.params;
return {
      headerRight: (                        //通过params为按钮绑定increase方法
<Button onPress={params.increase} title="+1" />
),
};
};
componentWillMount() {                    //通过setParams将increase方法绑定到_increase
this.props.navigation.setParams({ increase: this._increase });
}
  _increase=()=>{                           //设置state.count+1
this.setState(preState=>{return {count:preState.count+1}});
};
render() {
    return (
      <View style={styles.container}>
        <Text>计数为:{this.state.count}</Text>
      </View>
);
}
}

        在navigationOptions中的

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Karen110 Karen110
3年前
一篇文章带你了解JavaScript日期
日期对象允许您使用日期(年、月、日、小时、分钟、秒和毫秒)。一、JavaScript的日期格式一个JavaScript日期可以写为一个字符串:ThuFeb02201909:59:51GMT0800(中国标准时间)或者是一个数字:1486000791164写数字的日期,指定的毫秒数自1970年1月1日00:00:00到现在。1\.显示日期使用
Wesley13 Wesley13
3年前
java将前端的json数组字符串转换为列表
记录下在前端通过ajax提交了一个json数组的字符串,在后端如何转换为列表。前端数据转化与请求varcontracts{id:'1',name:'yanggb合同1'},{id:'2',name:'yanggb合同2'},{id:'3',name:'yang
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
10个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这