『React Navigation 3x系列教程』之React Navigation 3x开发指南

  • 文章介绍
  • 评价建议
  • 温馨提示:
    本站为源代码分享站,源码多为网友投稿 我们没有对源码进行测试,不保证可用性、安全性以及版权归属。 因源码具有可复制性,一经购买 ,不得以任何形式退款。
    如需商业用途 请点击商业源码栏目,购买商业源码.
    客服QQ:977439673

    期待已久的新教程上线啦!解锁React Native开发新姿势,一网打尽React Native最新与最热技术,点我Get!!!

    随着React Navigation逐渐稳定,Navigator也被光荣的退休了。在React Native生态环境中需要一款可扩展且易于使用的导航组件,Navigator 自然胜任不了,这时React Native社区便孕育出了一个开源导航组件React Navigation。

    React Navigation的出现替代了Navigator、 Ex-Navigation等老一代的导航组件,React Navigation可以说是Navigator的加强版,不仅有Navigator的全部功能,另外还支持底部导航类似于与iOS中的UITabBarController,此外它也支持侧拉效果方式的导航类似于Android中的抽屉效果。

    这篇文章将向大家分享React Navigation3x开发的一些实用技巧,以及从navigator到React Navigation的一些实战经验。

    提示:和本文配套的还有一个React Navigation3x的视频教程,欢迎学习。

    什么是导航器?

    导航器也可以看成一个是普通的React组件,你可以通过导航器来定义你的App的导航结构。 导航器还可以渲染通用元素,例如可以配置的标题栏和选项卡栏。

    在React Navigation中有以下7种类型的导航器:

    • createStackNavigator: 类似于普通的Navigator,屏幕上方导航栏;
    • createTabNavigator: createTabNavigator已弃用,使用createBottomTabNavigator和/或createMaterialTopTabNavigator替代;
    • createBottomTabNavigator:相当于iOS里面的TabBarController,屏幕下方的标签栏;
    • createMaterialTopTabNavigator:屏幕顶部的材料设计主题标签栏;
    • createDrawerNavigator: 抽屉效果,侧边滑出;
    • createSwitchNavigator:SwitchNavigator 的用途是一次只显示一个页面。

    你可以通过以上7种导航器来创建你APP,可以是其中一个也可以多个组合,这个可以根据具体的应用场景并结合每一个导航器的特性进行选择。

    在开始学习7种导航器之前,我们需要先了解两个和导航关于概念:

    • Screen navigation prop(屏幕导航属性):通过navigation可以完成屏幕之间的调度操作,例如打开另一个屏幕;
    • Screen navigationOptions(屏幕导航选项): 通过navigationOptions可以定制导航器显示屏幕的方式(例如:头部标题,选项卡标签等);

    导航器所支持的Props

    const SomeNav = createStackNavigator/createBottomTabNavigator/createMaterialTopTabNavigator/createDrawerNavigator/createSwitchNavigator({
      // config
    });
    
    <SomeNav
      screenProps={xxx}
      ref={nav => { navigation = nav; }}
      onNavigationStateChange=(prevState, newState, action)=>{
    
      }
    />
    
    • ref:可以通过ref属性获取到navigation
    • onNavigationStateChange(prevState, newState, action):顶级节点除了ref属性之外,还接受onNavigationStateChange(prevState, newState, action)属性,每次当导航器所管理的state发生改变时,都会回调该方法;
      • prevState:变化之前的state;
      • newState:新的state;
      • 导致state变化的action;
    • screenProps:向子屏幕传递额外的数据,子屏幕可以通过this.props.screenProps获取到该数据。

    Screen Navigation Prop(屏幕的navigation Prop)

    当导航器中的屏幕被打开时,它会收到一个navigation prop,navigation prop是整个导航环节的关键一员,接下来就详细讲解一下navigation的作用。

    • navigate:跳转到其他界面;
    • state:屏幕的当前state;
    • setParams:改变路由的params;
    • goBack:关闭当前屏幕;
    • dispatch:向路由发送一个action;
    • addListener:订阅导航生命周期的更新;
    • isFocused:true 标识屏幕获取了焦点;
    • getParam:获取具有回退的特定参数;
    • dangerouslyGetParent:返回父导航器;

    注意:一个navigation有可能没有navigate、setParams以及goBack,只有state与dispatch,所以在使用navigate时要进行判断,如果没有navigate可以使用navigation去dispatch一个新的action。如:

    const {navigation,theme,selectedTab}=this.props;
    const resetAction = StackActions.reset({
        index: 0,
        actions: [
            NavigationActions.navigate({
                routeName: 'HomePage',
                params:{
                    theme:theme,
                    selectedTab:selectedTab
                },
            })
        ]
    })
    navigation.dispatch(resetAction)
    

    提示:这里的reset在2.0及以后版本中被从NavigationActions中移到了StackActions中,使用时记得留意。

    StackNavigator的navigation的额外功能:

    当且仅当当前 navigator 是 stack navigator 时,this.props.navigation上有一些附加功能。 这些函数是 navigate 和 goBack 的替代方法, 你可以使用任何你喜欢的方法。 这些功能是:

    • this.props.navigation
      • push - 导航到堆栈中的一个新的路由
      • pop - 返回堆栈中的上一个页面
      • popToTop - 跳转到堆栈中最顶层的页面
      • replace - 用新路由替换当前路由
      • reset - 擦除导航器状态并将其替换为多个操作的结果
      • dismiss - 关闭当前栈

    使用navigate进行界面之间的跳转

    • navigation.navigate({routeName, params, action, key})navigation.navigate(routeName, params, action)
      • routeName:要跳转到的界面的路由名,也就是在导航其中配置的路由名;
      • params:要传递给下一个界面的参数;
      • action:如果该界面是一个navigator的话,将运行这个sub-action;
      • key:要导航到的路由的可选标识符。 如果已存在,将后退到此路由;
    export const AppStackNavigator = createStackNavigator({
        HomeScreen: {
            screen: HomeScreen
        },
        Page1: {
            screen: Page1
        })
    
    class HomeScreen extends React.Component {
      render() {
        const {navigate} = this.props.navigation;
    
        return (
          <View>
            <Text>This is HomeScreen</Text>
            <Button
              onPress={() => navigate('Page1', {name: 'Devio'})}
              title="Go to Page1"
            />
          </View>
         )
       }
    }
    

    在使用React Navigation3x过程中遇到任何问题都可以在React Navigation3x的视频教程中寻找答案哈。

    使用state的params

    可以通过this.props.state.params来获取通过setParams(),或navigation.navigate()传递的参数。

    <Button
        title={params.mode === 'edit' ? '保存' : '编辑'}
        onPress={() =>
            setParams({mode: params.mode === 'edit' ? '' : 'edit'})}
    />
    <Button
        title="Go To Page1"
        onPress={() => {
            navigation.navigate('Page1',{ name: 'Devio' });
        }}
    />
    const {navigation} = this.props;
    const {state, setParams} = navigation;
    const {params} = state;
    const showText = params.mode === 'edit' ? '正在编辑' : '编辑完成';
    

    使用setParams 改变route params

    • setParams: function setParams(params): 我们可以借助setParams来改变route params,比如,通过setParams来更新页面顶部的标题,返回按钮等;
    class ProfileScreen extends React.Component {
      render() {
        const {setParams} = this.props.navigation;
        return (
          <Button
            onPress={() => setParams({name: 'Lucy'})}
            title="Set title name to 'Lucy'"
          />
         )
       }
    }
    

    注意navigation.setParams改变的是当前页面的Params,如果要改变其他页面的Params可以通过NavigationActions.setParams完成,下文会讲到。 在使用React Navigation3x过程中遇到任何问题都可以在React Navigation3x的视频教程中寻找答案哈。

    使用goBack返回到上一页面或指定页面

    • goBack: function goBack(key):我们可以借助goBack返回到上一页或者路由栈的指定页面。
      • 其中key表示你要返回到页面的页面标识如id-1517035332238-4,不是routeName。
      • 可以通过指定页面的navigation.state.key来获得页面的标识。
      • key非必传,也可传null。

      navigation.state {params: {…}, key: "id-1517035332238-4", routeName: "Page1"}

    export default class Page1 extends React.Component {
        render() {
            const {navigation} = this.props;
            return <View style=>
                <Text style={styles.text}>欢迎来到Page1</Text>
                <Button
                    title="Go Back"
                    onPress={() => {
                        navigation.goBack();
                    }}
                />
            </View>
        }
    }
    

    通过dispatch发送一个action

    • dispatch: function dispatch(action):给当前界面设置action,会替换原来的跳转,回退等事件。
    const resetAction = StackActions.reset({
    	index: 0,
    	actions: [
    	    NavigationActions.navigate({
    	        routeName: 'HomePage',
    	        params:{
    	            theme:theme,
    	            selectedTab:selectedTab
    	        },
    	    })
    	]
    	})
    navigation.dispatch(resetAction)
    
    • Navigate : 导航到其他的页面;
    • Back : 返回到上一个页面;
    • Set Params : 设置指定页面的Params;
    • Init : 初始化一个 state 如果 state 是 undefined;

    Navigatie action会使用Navigate action的结果来更新当前的state。

    方法原型:navigate({routeName, params, action, key})

    • routeName:字符串,必选项,在app的router里注册的导航目的地的routeName。
    • params:对象,可选项,融合进目的地route的参数。
    • actions:对象,可选项(高级),如果screen也是一个navigator,次级action可以在子router中运行。在文档中描述的任何actions都可以作为次级action。
    • key: string or null 可选,要导航到的路由的标识符。如果已存在, 则导航回此路由。
    import { NavigationActions } from 'react-navigation'
    
    const navigateAction = NavigationActions.navigate({
      routeName: 'Profile',
      params: {},
      action: NavigationActions.navigate({ routeName: 'SubProfileRoute'})
    })
    this.props.navigation.dispatch(navigateAction)
    

    Back

    返回到前一个screen并且关闭当前screen.backaction creator接受一个可选的参数:

    方法原型:back(key)

    • key:String 可选,这个可以和上文中讲到的goBack的key是一个概念;
    import { NavigationActions } from 'react-navigation'
    const backAction = NavigationActions.back();
    this.props.navigation.dispatch(backAction);
    

    SetParams

    通过SetParams我们可以修改指定页面的Params。

    • params:对象,必选参数,将会被合并到已经存在页面的Params中。
    • key:字符串,必选参数,页面的key。
    import { NavigationActions } from 'react-navigation'
    const setParamsAction = NavigationActions.setParams({
        params: { title: 'HomePage' },
        key: 'id-1517035332238-4',
    });
    

    有很多小伙伴可能会问:navigation中有setParams为什么还要有NavigationActions.setParams?

    我从两方面来回答一下这个问题:

    1. 在上文中讲到过navigation中有可能只有state与dispatch,这个时候如果要修改页面的Params,则只能通过NavigationActions.setParams了;
    2. 另外,navigation.setParams只能修改当前页面的Params,而NavigationActions.setParams可以修改所有页面的Params;

    在使用React Navigation3x过程中遇到任何问题都可以在React Navigation3x的视频教程中寻找答案哈。

    StackActions

    • Reset : 重置当前 state 到一个新的state;
    • Replace : 使用另一个路由替换指定的路由;
    • Push : 在堆栈顶部添加一个页面,然后跳转到该页面;
    • Pop : 跳转到上一个页面;
    • PopToTop : 跳转到堆栈最顶层的页面,并销毁其他所有页面;

    Reset:

    Reset action删掉所有的navigation state并且使用这个actions的结果来代替。

    • index,数组,必选,navigation state中route数组中激活route的index。
    • actions,数组,必选项,Navigation Actions数组,将会替代navigation state。
    • key:string or null 可选, 如果设置,具有给定 key 的导航器将重置。 如果为null,则根导航器将重置。
    import { NavigationActions, StackActions } from 'react-navigation'
    
    const resetAction = StackActions.reset({
      index: 0,
      actions: [
        NavigationActions.navigate({ routeName: 'Profile'})
      ]
    })
    this.props.navigation.dispatch(resetAction)
    

    使用场景比如进入APP首页后的splash页不在使用,这时可以使用NavigationActions.reset重置它。

    index参数被用来定制化当前激活的route。举个例子:使用两个routes WelcomePage和HomePage给一个基础的stack navigation设置。为了重置route到HomePage,但是在堆栈中又存放在WelcomePage之上,你可以这么做:

    import { NavigationActions, StackActions } from 'react-navigation'
    
    const resetAction = StackActions.reset({
        index: 1,
        actions: [
            NavigationActions.navigate({ routeName: 'WelcomePage'}),
            NavigationActions.navigate({ routeName: 'HomePage'})
        ]
    });
    this.props.navigation.dispatch(resetAction);
    

    replace

    Replace - 用另一个路由替换指定的路由

    • key - string - 被替换的路由的 key,如果未指定,最近的路由将会被替换
    • newKey - string - 用于替换路线的 Key。 如果未提供,则自动生成。
    • routeName - string - routeName用于替换路由。
    • params - object - 要传入替换路由的参数。
    • action - object - 可选的子动作。
    • immediate* - boolean - 目前没有效果, 这是 stack navigator 支持动画替换(它目前不支持)的占位符。

    push

    Push - 在堆栈顶部添加一条路由,并导航至该路由. 与navigate的区别在于,如果有已经加载的页面,navigate方法将跳转到已经加载的页面,而不会重新创建一个新的页面。 push 总是会创建一个新的页面,所以一个页面可以被多次创建

    • routeName - string - routeName用于替换路由。
    • params - object - 将合并到目标路由的参数(通过this.props.navigation.state.params在目标路由获取)。
    • action - Object - 可选 - (高级)如果页面是 navigator,则是在子路由器中运行的子操作。
    import { StackActions } from 'react-navigation';
    
    const pushAction = StackActions.push({
      routeName: 'Profile',
      params: {
        myUserId: 9,
      },
    });
    
    this.props.navigation.dispatch(pushAction);
    

    pop

    The pop 一个可以返回到堆栈中上一个路由到方法,通过设置参数 n,可以指定返回的多少层。

    • n - number - 返回的层数
    import { StackActions } from 'react-navigation';
    
    const popAction = StackActions.pop({
      n: 1,
    });
    
    this.props.navigation.dispatch(popAction);
    

    popToTop

    popToTop 一个可以直接跳转到堆栈最顶层,并销毁其它所有页面的方法,它在功能上与StackActions.pop({n:currentIndex})相同。

    import { StackActions } from 'react-navigation';
    
    this.props.navigation.dispatch(StackActions.popToTop());
    

    如何支持Schema跳转?

    Deep Linking

    还有那些应用场景?

    在导航器屏幕之外使用导航功能(巧用导航器的ref)

    有一种场景:有的时候我们需要在导航器中所定义的屏幕之外使用导航器来做页面跳转。

    • 屏幕之间的跳转是需要借助navigation来完成的;
    • 我们知道导航器中定义的屏幕可以通过const {navigation} = this.props;来获取navigation
    • 那么,如果我们在非导航器中所定义的屏幕中做屏幕跳转的关键一步,就是要想法获取navigation
    • 那么,如何才能在非导航器中所定义的屏幕中获取到这个navigation呢?

    下面就给大家讲解通过ref属性还获得navigation

    示例看代码:

    import { NavigationActions } from 'react-navigation';
    
    const AppNavigator = StackNavigator(SomeAppRouteConfigs);
    
    class App extends React.Component {
      someEvent() {
        // call navigate for AppNavigator here:
        this. navigation && this. navigation.dispatch(
          NavigationActions.navigate({ routeName: someRouteName })
        );
      }
      render() {
        return (
          <AppNavigator ref={nav => { navigation = nav; }} />
        );
      }
    }
    

    上述代码通过导航器的顶级节点ref属性获取到navigation,当上述代码的AppNavigator节点被渲染时,ref会被回调这是就可以获取到navigation了,需要提醒大家的是,这种用法对除StackNavigator之外的其他两种类型的导航器也是实用的哦;

    Leave a Reply

  • 如本资源侵犯了您的权益,[email protected]!我们将在收到邮件的1个小时内处理完毕。

  • 本站仅为平台,发布的资源均为用户投稿或转载!所有资源仅供参考学习使用,请在下载后的24小时内删除,禁止商用!

  • OKMG(芒果源码)助力正版,如您有自己的原创产品,可以联系客服投稿,代理出售!

  • OKMG(芒果源码)客服QQ:29139260

  • OKMG(芒果源码)商务电话(仅对企业客户/个人用户请联系QQ客服):010-86463891

  • 请注意:本站不提供任何免费的技术咨询服务,为了节约时间,下载前 请确认自己会技术
  • 免责声明 芒果源码,一个精品商业网站源码分享平台 WWW.OKMG.CN 1. 本站所有资源来源于用户上传和网络,均不允许转载,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除! 3. 如发现会员转载本站资源文章,本站有权封禁会员账号! 4. 不得使用于非法商业用途,不得违反国家法律。否则后果自负! 5. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 6. 如有链接无法下载、失效或广告,请联系管理员处理! 7. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 8. 如遇到加密压缩包,默认解压密码为"www.okmg.cn",如遇到无法解压的请联系管理员! 9.本站客服:29139260

    售后服务:

    • 售后服务范围 1、商业模板使用范围内问题免费咨询
      2、源码安装、模板安装(一般 ¥50-300)服务答疑仅限SVIP用户
      3、单价超过200元的模板免费一次安装,需提供服务器信息。
      付费增值服务 1、提供dedecms模板、WordPress主题、discuz模板优化等服务请详询在线客服
      2、承接 WordPress、DedeCMS、Discuz 等系统建站、仿站、开发、定制等服务
      3、服务器环境配置(一般 ¥50-300)
      4、网站中毒处理(需额外付费,500元/次/质保三个月)
      售后服务时间 周一至周日(法定节假日除外) 9:00-23:00
      免责声明 本站所提供的模板(主题/插件)等资源仅供学习交流,若使用商业用途,请购买正版授权,否则产生的一切后果将由下载用户自行承担,有部分资源为网上收集或仿制而来,若模板侵犯了您的合法权益,请来信通知我们(Email: [email protected]),我们会及时删除,给您带来的不便,我们深表歉意!

    Hi, 如果你对这款模板有疑问,可以跟我联系哦!

    联系客服
    开通VIP 享更多特权,建议使用 QQ 登录
    /** * 项目名称:用户离开标题切换 */