本文共 6900 字,大约阅读时间需要 23 分钟。
createStackNavigator ==> createSwitchNavigator ==> createAppContainer
createBottomTabNavigator ==> 自定义的底部Tab
NavigationActions 和 StackActions 可以获取navigation的方法名
详细请看:
1. 应用中的每个页面组件都会自动提供 this.props.navigation
this.props.navigation可以获取的一些方法:
navigate
- 转到另一个页面, 计算出需要执行的操作 (常用)goBack
- 关闭活动屏幕并在堆栈中向后移动 (常用)addListener
- 订阅导航生命周期的更新isFocused
- 函数返回 true
如果屏幕焦点和 false
否则。state
- 当前状态/路由 (常用)setParams
- 对路由的参数进行更改 (常用)getParam
- 获取具有回退的特定参数 (常用)dispatch
- 向路由发送 action (常用)dangerouslyGetParent
- 返回父级 navigator 的函数注意: 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
- 用新路由替换当前路由dismiss
- 关闭当前堆栈3. 如果是DrawerNavigator,除了以上方法,this.props.navigation还提供如下的一些方法:
openDrawer
- 打开closeDrawer
- 关闭toggleDrawer
- 切换,如果是打开则关闭,反之亦然由于笔者没有使用过DrawerNavigator,在此就不做说明;
以上内容均摘自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({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
========================================================================
==》阻止多次点击重复跳转同一页面
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 方法也要随着修改,灵活一点。。。
转载地址:http://tsqni.baihongyu.com/