美文网首页react native
React Native中页面跳转、传值与回调

React Native中页面跳转、传值与回调

作者: 袁俊亮技术博客 | 来源:发表于2016-12-05 14:03 被阅读2700次

React Native中页面跳转、传值与回调

标签(空格分隔): React


React Native中页面跳转、传值与回调

React Native封装了许多控件,并且提供了比较详细的文档和代码片段,但并不是所有的示例都能够清楚的说明这些控件的用法,其中就包括重要的Navigator(导航控制器)。官方的文档中贴了许多代码,但并没有说清楚它是怎么工作的。
在iOS中,我们使用UINavigationController管理多个页面,每个被它所管理的页面都有一个引用指向所在的导航控制器对象。我们可以很方便的利用这个特性管理页面(pushpop)。不过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",
    }
});

参考资料:

http://www.jianshu.com/p/722c64adc367

http://www.jianshu.com/p/62f86a8714ec

相关文章

网友评论

    本文标题:React Native中页面跳转、传值与回调

    本文链接:https://www.haomeiwen.com/subject/snwkmttx.html