美文网首页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