一、react-navigation的初使用

createStackNavigator  ==> createSwitchNavigator  ==>  createAppContainer

createBottomTabNavigator ==> 自定义的底部Tab

NavigationActions 和 StackActions 可以获取navigation的方法名

二、this.props.navigation使用的方法和属性

详细请看: react-navigation 3.x版本的push、navigate、goback、pop、dispatch等常用方法

1. 应用中的每个页面组件都会自动提供 this.props.navigation

this.props.navigation可以获取的一些方法:

 navigate - 转到另一个页面, 计算出需要执行的操作  (常用)
goBack - 关闭活动屏幕并在堆栈中向后移动  (常用)
addListener - 订阅导航生命周期的更新
isFocused - 函数返回 true 如果屏幕焦点和 false 否则。
state - 当前状态/路由  (常用)
setParams - 对路由的参数进行更改  (常用)
getParam - 获取具有回退的特定参数  (常用)
dispatch - 向路由发送 action  (常用)
dangerouslyGetParent - 返回父级 navigator 的函数

navigation的方法

注意: this.props.navigation并不是在所有页面(组件)中都可以使用,而是必须在StackNavigator、DrawerNavigator中声明的screen组件,才可以使用this.props.navigation

也就是说,screen组件会自动获得这个props

this.props.navigation 上还有一些方法取决于当前 navigator 的附加函数(StackNavigator 和 DrawerNavigator)

2. 如果是StackNavigator,除了以上方法,this.props.navigation还提供如下的一些方法:

 push - 推一个新的路由到堆栈  (常用)
pop - 返回堆栈中的上一个页面  (常用)
popToTop - 跳转到堆栈中最顶层的页面  (常用)
replace - 用新路由替换当前路由
reset- 操作会擦除整个导航状态,并将其替换为多个操作的结果。  (常用)
dismiss - 关闭当前堆栈

StackNavigator的方法

3. 如果是DrawerNavigator,除了以上方法,this.props.navigation还提供如下的一些方法:

 openDrawer - 打开
closeDrawer - 关闭
toggleDrawer - 切换,如果是打开则关闭,反之亦然

DrawerNavigator的方法

由于笔者没有使用过DrawerNavigator,在此就不做说明;

以上内容均摘自react-navigation的官网,但是官网有点繁琐,写此以自用,有读者也是我的幸运。

三、react-navigation的特殊方法

===============================================================

==> 清空堆栈,跳转指定页面

import {NavigationActions, StackActions} from 'react-navigation'

const resetAction = StackAction.reset({
  index: 0,
  actions: [NAvigationActions.navigate({ routeName: 'HomeScreen'})], });
//使用
this.props.navigation.dispatch(resetaction)

说明: 上面的方法是使用dispatch重写了reset方法,

也可以直接使用reset方法:this.props.navigation.reset()

import { NavigationActions } from 'react-navigation';
navigation.reset([NavigationActions.navigate({ routeName: 'HomeScreen' })], 0)

========================================================================

//在不在StackNavigation的堆栈中的页面,如何使用navigation

1.在主Navigator的组件中添加ref,并导出

//StackNavigator来自createStackNavigator方法
const MainNavigator = createAppContainer(StackNavigator); import {setTopLevelNavigator} from 'xxx.js' export default calss Navigator extends Component{
render() {
return(
<MainNavigator
   ref={navigatorRef => {setTopLevelNavigator(navigatorRef )}}    //setTopLevelNavigator来自需要使用的页面
       />
)
}
}

说明: 将MainNavigator 通过ref 传递给 其他页面传过来的 setTopLevelNavigator

2.在需要使用的页面,接收这个ref引用,如xxx.js

let  _navigator;

export function setTopLevelNavigator(navigatorRef ) {
  _navigator = navigatorRef
}
// 定义navigate 方法
function navigate(routeName, params) {
  _navigator && _navigator.dispatch(
   NavigationActions.navigate({
    type: NavigationActions.NAVIGATE,
    routeName,
    params
  })
  )
}
// 定义dispatch方法
function dispatch(params) {
  _navigator && _navigator.dispatch(
     params
  )
} //使用,直接使用上面的方法即可
dispatch(resetAction)  //resetAction同上   navigate("Home", {title: 'profile'})

说明: 通过setTopLevelNavigator去主导航页面接收navigation相关的方法

另外: 使用withNavigation(Component) 可以使得组件携带navigation相关的方法

withNavigation是一个更高阶的组件,它将navigationprop 传递给一个包装组件。当你不能navigation直接将prop 传递给组件时,或者在深度嵌套的子级的情况下不想传递它时,它很有用。

withNavigation(Component) 返回一个Component。

import React from 'react';
import { Button } from 'react-native';
import { withNavigation } from 'react-navigation'; class MyBackButton extends React.Component {
render() {
return <Button title="Back" onPress={() => { this.props.navigation.goBack() }} />; //此处可以使用navigation相关方法
}
}
// withNavigation returns a component that wraps MyBackButton and passes in the
// navigation prop
export default withNavigation(MyBackButton);

========================================================================

==》阻止多次点击重复跳转同一页面

const navigateOnce = (getStateForAction) => (action, lastState) => {
  const {type, routeName, params} = action;
   return (
    lastState &&
    (type === StackActions.PUSH) && //此处原先使用NavigationActions.NAVIGATE
    routeName === lastState.routes[lastState.routes.length - 1].routeName &&
    JSON.stringify(params) === JSON.stringify(lastState.routes[lastState.routes.length - 1].params)
  ) ? null : getStateForAction(action, lastState)
} //使用,MainNavigator是主导航页面通过createAppContainer方法的返回值
MainNavigator.router.getStateForAction = navigateOnce(MainNavigator.router.getStateForAction)

说明: MainNavigator经过 getStateForAction 检查校验,阻止多次点击跳转相同页面的情况发生

注意: 当你使用createSwitchNavigator时,就在路由数组外在套上一层switch数组,所以 lastState.routes[lastState.routes.length - 1] 可能取不到想要的值,因为还有一层数组

6月26日修改:

当使用了createSwitchNavigator时,修改上面的 navigateOnce 方法

const MainSwitch = createSwitchNavigator({
MainStack: MainStack,
... //其他
}) const MainNavigator = createAppContainer(MainSwitch); const navigateOnce = (getStateForAction) => (action, lastState) => {
   const {type, routeName, params} = action;
//此处需要注意,使用了createSwitchNavigator后,lastState.routes[lastState.routes.length - 1]拿不到我们想要的那个对象
const mainStackRoutes = lastState && lastState.routes.find((item)=>item.key === "MainStack"); //拿到我们想要的那个对象
   return (
    mainStackRoutes &&
    (type === StackActions.PUSH) && //此处原先使用NavigationActions.NAVIGATE
    routeName === mainStackRoutes .routes[mainStackRoutes .routes.length - 1].routeName &&
    JSON.stringify(params) === JSON.stringify(mainStackRoutes .routes[mainStackRoutes .routes.length - 1].params)
  ) ? null : getStateForAction(action, lastState)
} //使用,MainNavigator是主导航页面通过createAppContainer方法的返回值
MainNavigator.router.getStateForAction = navigateOnce(MainNavigator.router.getStateForAction)

但是,当我们使用了createSwitchNavigator时,又使用了createDrawerNavigator,于是,再次修改上面的 navigateOnce 方法

const MainDrawer = createDrawerNavigator({
MainStack: MainStack,
... //其他
}, {
order: ['MainStack'],
initialRouteName: 'MainStack',
...
}) const MainSwitch = createSwitchNavigator({
MainDrawer : MainDrawer ,
StartPresentation: StartPresentation, //APP启动页
... //其他
}, {
initialRouteName: 'StartPresentation',
...
}) const MainNavigator = createAppContainer(MainSwitch); const navigateOnce = (getStateForAction) => (action, lastState) => {
  const {type, routeName, params} = action;
//使用了createDrawerNavigator后,上面的方法也拿不到我们想要的对象
const mainDrawerRoutes = lastState && lastState.routes.find((item)=>item.key === "MainDrawer "); //拿到我们想要的那个对象
//此处需要注意,使用了createSwitchNavigator后,lastState.routes[lastState.routes.length - 1]拿不到我们想要的那个对象
const mainStackRoutes = mainDrawerRoutes&& mainDrawerRoutes.routes.find((item)=>item.key === "MainStack"); //拿到我们想要的那个对象    return (
    mainStackRoutes &&
    (type === StackActions.PUSH) && //此处原先使用NavigationActions.NAVIGATE
    routeName === mainStackRoutes .routes[mainStackRoutes .routes.length - 1].routeName &&
    JSON.stringify(params) === JSON.stringify(mainStackRoutes .routes[mainStackRoutes .routes.length - 1].params)
  ) ? null : getStateForAction(action, lastState)
} //使用,MainNavigator是主导航页面通过createAppContainer方法的返回值
MainNavigator.router.getStateForAction = navigateOnce(MainNavigator.router.getStateForAction)

总而言之,当我们修改navigation代码结构时,navigateOnce 方法也要随着修改,灵活一点。。。

react-navigation的多次点击重复跳转同一页面、不在堆栈路由页面使用navigation方法的解决思路的更多相关文章

  1. 利用 runtime,解决多次点击相同 button,导致重复跳转的问题-b

    当app有点卡的时候,多次点击相同的button,经常出现,跳转了N次相同的界面(比如闲鱼) 解决办法 用运行时和分类,替换 UIControl 响应事件,根据响应的间隔时间来判断是否执行事件. 详细 ...

  2. 使用Android点击按钮跳转页面

    1.首先新建一个Android工程,命名为MyApp(名字可以自己随意起); 2.以原有的MainActivity.java文件为登录界面,然后在src文件中的包上面右击选择New目录下的Other中 ...

  3. 如何绑定android点击事件--跳转到另一个页面并实现关闭功能?

    一.点击按钮跳转到另一个页面. eg:实现从一个页面点击跳转到另一个页面 1.首先在一个布局文件(.XML)中绘画了一个跳转按钮(id为btn1): <Button         androi ...

  4. window.location.href问题,点击,跳转到首页

    onClick="window.location.href='./';" 点击,跳转到首页. location.href=url Js中实现跳转 window.location.h ...

  5. 安卓入门——————简单记账本的开发(二)-点击listview跳转并实现数据的更新

    前言:   这个博客主要实现listview的跳转并实现对数据库内容的更新并显示到listview上,还没有实现listview的实时更新和listview具体线条的添加(接下来的几篇博客会实现),如 ...

  6. mui中confirm在苹果出现bug,confirm点击确定跳转页面再返回后,页面被遮罩盖住无法使用

    项目中使用confirm mui.confirm('您还未抽奖,现在去抽奖吗?', function (res) { if (res.index === 1) { window.location.hr ...

  7. a标签点击不跳转的几种方法

    a标签点击不跳转的几种方法 1.onclick事件中返回false <a href="http://www.baidu.com" onclick="return f ...

  8. div加链接 html给div加超链接实现点击div跳转的方法[申明:来源于网络]

    div加链接 html给div加超链接实现点击div跳转的方法[申明:来源于网络] 地址:http://www.cdxwcx.com/faq/htmldivLink.html

  9. <a>标签点击不跳转

    HTML中的<a></a>标签点击不跳转的方法 一.<a href="####" ></a> 使用这个方法我们会发现<a hr ...

随机推荐

  1. 201621123005《Java程序设计》第十三次实验总结

    <Java程序设计>第十三周实验总结 1. 本周学习总结 以你喜欢的方式(思维导图.OneNote或其他)归纳总结多网络相关内容. 2. 为你的系统增加网络功能(购物车.图书馆管理.斗地主 ...

  2. 201621123006 《Java程序设计》第9周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结集合与泛型相关内容. 2. 书面作业 本次作业题集集合 List中指定元素的删除(题集题目) 1.1 实验总结.并回答:列举至少2种 ...

  3. PHP ksort() 函数

    PHP ksort() 函数 PHP Array 函数 实例 按照键名对关联数组进行升序排序: <?php $age=array("Bill"=>"60&qu ...

  4. C++ 4 种具有更 为准确语义的新强制转换类型

    1. static_cast<T>() 可用于把指向A 的指针强制转换为指向B 的指针,其约束条件是类B必须是类A的子类.例如:A *obj = new B;B *b = static_c ...

  5. [笔记]CodeIgniter的SESSION

         由于HTTP协议本身是无状态的,所以当保留某个用户的访问状态信息时,需要客户端有一个唯一标识传给服务端,这个唯一标识就是SESSION ID,存放在客户端的COOKIE中,然后服务端根据该标 ...

  6. Java反射机制的使用

    一:反射是什么 JAVA反射机制是在运行状态中,对于任意一个类,都能够获取这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取类信息以及动态调用对象内容就称为jav ...

  7. swift3.0 创建经典界面的九宫图

    网络上很多例子都是早期的 Object-C的效果,现在用到Swift3.0开发,故把网络上的例子翻译过来,达到基本的效果.可是现在这个还不算很满意,再下次继续进行优化 override func vi ...

  8. 【idea】Error:java: Compilation failed: internal java compiler error 解决办法

    报错信息: 报错原因: 项目中Java版本不一致,可以查看项目中的jdk配置 1.查看项目的jdk(Ctrl+Alt+shift+S) File ->Project Structure-> ...

  9. Java多线程编程核心技术,第三章

    1,notify的同步块完了,才会运行wait的同步块 2,interrupt()不是静态方法,用在wait的线程上会有InteruptException,锁也会被释放 3,notify()唤醒的线程 ...

  10. sublime text 2 卸载与重装

    很多同学使用 sublime text2 的时候,出现一些奇怪的bug,且重启无法修复. 于是,就会想到卸载 sublime text2 再重新安装. 然而,你会发现,重新安装后,这个bug任然存在, ...