理解navigator

2016-04-06  本文已影响366人  lyzaijs

重新排版 理解navigator

这是一个简单的例子,用Navigator来跳转页面,页面之间传递参数 (代码是ES6语法写的):

import React,{
    View,
    Navigator
} from 'react-native';
import FirstPageComponent from './FirstPageComponent';

export default class SampleComponent extends React.Component {
    render() {
        let defaultName = 'FirstPageComponent';
        let defaultComponent = FirstPageComponent;
        return (
        <Navigator
          initialRoute={{ name: defaultName, component: defaultComponent }}
          configureScene={(route) => {
            return Navigator.SceneConfigs.VerticalDownSwipeJump;
          }}
          renderScene={(route, navigator) => {
            let Component = route.component;
            return <Component {...route.params} navigator={navigator} />
          }} />
        );
    }
} 

这里来解释一下代码:

第三行: 一个初始首页的component名字,比如我写了一个component叫HomeComponent,那么这个name就是这个组件的名字【HomeComponent】了。

第四行: 这个组件的Class,用来一会儿实例化成 <Component />标签

第七行:
`initialRoute={{ name: defaultName, component: defaultComponent }}
这个指定了默认的页面,也就是启动app之后会看到界面的第一屏。 需要填写两个参数: name 跟 component。

第八,九,十行:
configureScene={() => {return Navigator.SceneConfigs.VerticalDownSwipeJump;}}
这个是页面之间跳转时候的动画,具体有哪些?可以看这个目录下,有源代码的: node_modules/react-native/Libraries/CustomComponents/Navigator/NavigatorSceneConfigs.js

最后的几行:
renderScene={(route, navigator) => { let Component = route.component; return <Component {...route.params} navigator={navigator} /> }} /> );

(这是也默认自定义的route,内部内容可以自行扩展,在renderScene中接收也是这个,如果在其他js中使用navigator.push方式进行页面切换,则内容的id要与此保持一致 ,每一次页面切换都会重新调用一次renderScene`) - id指 initialRoute中的 name 与 component

这里是每个人最疑惑的,我们先看到回调里的两个参数:route, navigator。通过打印我们发现route里其实就是我们传递的name,component这两个货,navigator是一个Navigator的对象,为什么呢,因为它有push pop jump...等方法,这是我们等下用来跳转页面用的那个navigator对象。

return <Component {...route.params} navigator={navigator} />

这里有一个判断,也就是如果传递进来的component存在,那我们就是返回一个这个component,结合前面 initialRoute 的参数,我们就是知道,这是一个会被render出来给用户看到的component,然后navigator作为props传递给了这个component。

所以下一步,在这个FirstPageComponent里面,我们可以直接拿到这个 props.navigator:

import React,{
    View,
    Text,
    TouchableOpacity
} from 'react-native';

import SecondPageComponent from './SecondPageComponent';

export default class FirstPageComponent extends React.Component {
    constructor(props) {
        super(props);
        this.state = {};
    }
    _pressButton() {
        const { navigator } = this.props;
        //为什么这里可以取得 props.navigator?请看上文:
        //<Component {...route.params} navigator={navigator} />
        //这里传递了navigator作为props
        if(navigator) {
            navigator.push({
                name: 'SecondPageComponent',
                component: SecondPageComponent,
            })
        }
    }
    render() {
        return (
            <View>
                <TouchableOpacity onPress={this._pressButton.bind(this)}>
                    <Text>点我跳转</Text>
                </TouchableOpacity>
            </View>
        );
    }
}

这个里面创建了一个可以点击的区域,让我们点击可以跳到SecondPageComponent这个页面,实现页面的跳转。现在来创建SecondPageComponent,并且让它可以再跳回FirstPageComponent:

import React, {
    View,
    Text,
    TouchableOpacity,
} from 'react-native';

import FirstPageComponent from './FirstPageComponent';

export default class SecondPageComponent extends React.Component {

    constructor(props) {
        super(props);
        this.state = {};
    }

    _pressButton() {
        const { navigator } = this.props;
        if(navigator) {
            //很熟悉吧,入栈出栈~ 把当前的页面pop掉,这里就返回到了上一个页面:FirstPageComponent了
            navigator.pop();
        }
    }

    render() {
    return (
            <View>
                <TouchableOpacity onPress={this._pressButton.bind(this)}>
                    <Text>点我跳回去</Text>
                </TouchableOpacity>
            </View>
    );
    }
}

大功告成,能进能出了。

关于官方文档里有个东西,这里说一下:

这些都是navigator可以用的public method,就是跳转用的,里面有些带参数的XXX(route),新手第一次看这个文档会疑惑,这个route参数是啥呢,这个route就是:renderScene={(route, navigator) =>这里的route,最基本的route就是:var route = { component: LoginComponent}

这种格式。这个地方有点模糊的,在这里先说清楚了。

然后下面要讨论,怎么传递参数过去,或者从对方获取参数。
传递参数,通过push就可以了。
比如在一个 press的事件里:

//FirstPageComponent.js
import React, {
    View,
    Text,
    TouchableOpacity
} from 'react-native';

import SecondPageComponent from './SecondPageComponent';

export default class FirstPageComponent extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
            id: 2
        };
    }


    _pressButton() {
        const { navigator } = this.props;
        if(navigator) {
            navigator.push({
                name: 'SecondPageComponent',
                component: SecondPageComponent,
                //这里多出了一个 params 其实来自于<Navigator 里的一个方法的参数...
                params: {
                    id: this.state.id
                }
            });
        }
    }

    render() {
        return (
            <View>
                <TouchableOpacity onPress={this._pressButton.bind(this)}>
                    <Text>点我跳转并传递id</Text>
                </TouchableOpacity>
            </View>
        );
    }
}

params的来历:

// index.ios.js
<Navigator
  initialRoute={{ name: defaultName, component: defaultComponent }}
  configureScene={() => {
    return Navigator.SceneConfigs.VerticalDownSwipeJump;
  }}
  renderScene={(route, navigator) => {
    let Component = route.component;
    if(route.component) {
        //这里有个 { ...route.params }
        return <Component {...route.params} navigator={navigator} />
    }
  }} />

这个语法是把 routes.params 里的每个key 作为props的一个属性:

navigator.push({
    name: 'SecondPageComponent',
    component: SecondPageComponent,
    params: {
        id: this.state.id
    }
});

这里的 params.id 就变成了 <Navigator id={} 传递给了下一个页面。所以 SecondPageComponent就应该这样取得 id:

//SecondPageComponent.js
import React,{
    View,
    Text,
    TouchableOpacity,
} from 'react-native';

import FirstPageComponent from './FirstPageComponent';

export default class SecondPageComponent extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
            id: null
        }
    }

    componentDidMount() {
        //这里获取从FirstPageComponent传递过来的参数: id
        this.setState({
            id: this.props.id
        });
    }

    _pressButton() {
        const { navigator } = this.props;
        if(navigator) {
            navigator.pop();
        }
    }

    render() {
        return (
            <View>
                <Text>获得的参数: id={ this.state.id }</Text>
                <TouchableOpacity onPress={this._pressButton.bind(this)}>
                    <Text>点我跳回去</Text>
                </TouchableOpacity>
            </View>
        );
    }
}

这样在页面间传递的参数,就可以获取了。

上一篇下一篇

猜你喜欢

热点阅读