React Native中页面跳转、传值与回调
标签(空格分隔): React
React Native中页面跳转、传值与回调
React Native封装了许多控件,并且提供了比较详细的文档和代码片段,但并不是所有的示例都能够清楚的说明这些控件的用法,其中就包括重要的Navigator(导航控制器)
。官方的文档中贴了许多代码,但并没有说清楚它是怎么工作的。
在iOS中,我们使用UINavigationController
管理多个页面,每个被它所管理的页面都有一个引用指向所在的导航控制器对象。我们可以很方便的利用这个特性管理页面(push
和pop
)。不过React Native中的Navigator的使用方式不一样,它使用一个集中的路由机制控制页面的跳转,下面我们会通过一个简单的例子详细进行讲解。
ReactNative代码基本机构
首先我们应该创建了一个ReactNative工程,如果不知道怎么创建可以参考官方文档,官方文档对于这一块讲的还算比较清晰。
下面我们简单了解一下ReactNative的基本结构及各部分的作用
以index.ios.js
为例。默认该文件中有许多自动生成的代码,将其修改为以下样子。
//1. 导入react框架中的内容
import React, { Component } from 'react';
//2. 导入react-native框架中的内容
import {
//3. 必须,注册应用(App)时使用
AppRegistry,
} from 'react-native';
//4. 创建应用
class NavigatorDemo extends Component {
render() {
return (
//5. 编写应用的渲染代码
);
}
}
//5. 注册应用组件
AppRegistry.registerComponent('NavigatorDemo', () => NavigatorDemo);
ReactNative的基本结构还算比较清晰。了解完他们之间的基本结构以后。下面就开始看Navigator
的使用方法
Navigator的使用
index.ios.js文件
// 导入React基础组件
import React from 'react';
import {
View,
Navigator,
AppRegistry
} from 'react-native';
// 导入自定义组件
import FirstPageComponent from './FirstPageComponent';
// export default 是导出默认类,一定不能忘记export default导出
export default class demo extends React.Component {
render() {
let defaultName = 'FirstPageComponent';
// 控制器的跳转是根据这个参数信息来进行路由查找的
let defaultComponent = FirstPageComponent;
return (
<Navigator
// 初始化路由,导航控制器是通过component参数来查找要跳转到的控制器
initialRoute={{ name: defaultName, component: defaultComponent }}
// 设置导航控制器的跳转方式
configureScene={(route) => {
return Navigator.SceneConfigs.HorizontalSwipeJumpFromRight;
}}
// 渲染场景
renderScene={(route, navigator) => {
let Component = route.component;
//这个语法是把 routes.params 里的每个key作为props的一个属性,在下个页面即可用this. props.id调用
//navigator对象在导航容器跳转时一直存在
return <Component {...route.params} navigator={navigator} />
}}
/>
);
}
}
AppRegistry.registerComponent('demo', () => demo);
FirstPageComponent
import React from 'react';
import {
View,
Navigator,
TouchableOpacity,
Text,
StyleSheet
} from 'react-native';
import SecondPageComponent from './SecondPageComponent';
export default class FirstPageComponent extends React.Component {
// 构造方法初始化后续需要用到的数据参数,该方法在已进入这个页面的时候会调用一次,从后面页面回来的时候不会调
constructor(props) {
// 初始化父类的属性信息
super(props);
// 初始化本页面可能会用到的属性信息
this.state = {
id: 2,
user: null,
}
}
_pressButton() {
// 这里保存一下是为了防止后续事件操作的时候this的执行改变
let _this = this;
//为什么这里可以取得 props.navigator?请看上文:
//<Component {...route.params} navigator={navigator} />
//这里传递了navigator作为props
const { navigator } = this.props;
if(navigator) {
navigator.push({
name: 'SecondPageComponent',
// 导航控制器是通过该参数来查找跳转到哪一个控制器
component: SecondPageComponent,
//这里多出了一个 params 其实来自于<Navigator 里的一个方法的参数...
//routes.params 里的每个key 作为props的一个属性:
//这里的 params.id 就变成了 <Navigator id={} 传递给了下一个页面
params: {
id: this.state.id,
//回调!从SecondPageComponent获取user
getUser: function(user) {
_this.setState({
user: user
})
}
}
});
}
}
// 渲染页面
render() {
if( this.state.user ) {
return(
<View>
<Text style={styles.container}>用户信息: { JSON.stringify(this.state.user) }</Text>
</View>
);
}else {
return(
<View>
<TouchableOpacity onPress={this._pressButton.bind(this)}>
<Text style={styles.container}>查询ID为{ this.state.id }的用户信息</Text>
</TouchableOpacity>
</View>
);
}
}
}
// 设置样式
const styles = StyleSheet.create({
container:{
marginTop:50,
width:300,
height:100,
backgroundColor:"red",
}
});
SecondPageComponent
// 初始化数据模型
const USER_MODELS = {
1: { name: 'mot', age: 23 },
2: { name: '晴明大大', age: 25 }
};
import React from 'react';
import {
View,
Navigator,
Text,
TouchableOpacity,
StyleSheet
} from 'react-native';
import FirstPageComponent from './FirstPageComponent';
// 导出模块
export default class SecondPageComponent extends React.Component {
// 初始化模块信息
constructor(props) {
super(props);
this.state = {
id: null
}
}
// 当页面加载完成的时候会调用一次,相当于IOS中的ViewDidLoad方法
componentDidMount() {
//这里获取从FirstPageComponent传递过来的参数: id
this.setState({
id: this.props.id
});
}
_pressButton() {
const { navigator } = this.props;
// 如果上一页面有getUser方法再执行下面的方法
if(this.props.getUser) {
let user = USER_MODELS[this.props.id];
//回调传值给上个页面
this.props.getUser(user);
}
if(navigator) {
//出栈,返回到上一页
navigator.pop();
}
}
render() {
return(
<View>
<Text>获得的参数: id={ this.state.id }</Text>
<TouchableOpacity onPress={this._pressButton.bind(this)}>
<Text style={styles.container}>点我跳回去</Text>
</TouchableOpacity>
</View>
);
}
}
// // 设置样式
const styles = StyleSheet.create({
container:{
marginTop:50,
width:300,
height:100,
backgroundColor:"red",
}
});
参考资料:
网友评论