美文网首页
理解navigator

理解navigator

作者: lyzaijs | 来源:发表于2016-04-06 14:30 被阅读366次

    重新排版 理解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>
        );
        }
    }
    

    大功告成,能进能出了。

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

    • getCurrentRoutes() - 获取当前栈里的路由,也就是push进来,没有pop掉的那些
    • jumpBack() - 跳回之前的路由,当然前提是保留现在的,还可以再跳回来,会给你保留原样。
    • jumpForward() - 上一个方法不是调到之前的路由了么,用这个跳回来就好了
    • jumpTo(route) - Transition to an existing scene without unmounting
    • push(route) - Navigate forward to a new scene, squashing any scenes that you could jumpForward to
    • pop() - Transition back and unmount the current scene
    • replace(route) - Replace the current scene with a new route
    • replaceAtIndex(route, index) - Replace a scene as specified by an index
    • replacePrevious(route) - Replace the previous scene
    • immediatelyResetRouteStack(routeStack) - Reset every scene with an array of routes
    • popToRoute(route) - Pop to a particular scene, as specified by its route. All scenes after it will be unmounted
    • popToTop() - Pop to the first scene in the stack, unmounting every other scene

    这些都是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>
            );
        }
    }
    

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

    相关文章

      网友评论

          本文标题:理解navigator

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