1. 程式人生 > >react-navigation的多次點擊重復跳轉同一頁面、不在堆棧路由頁面使用navigation方法的解決思路

react-navigation的多次點擊重復跳轉同一頁面、不在堆棧路由頁面使用navigation方法的解決思路

xtend iss 需要 點擊 定義 cti 並不是 navi 而是

一、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 的函數

註意: 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 - 關閉當前堆棧

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

  • openDrawer - 打開
  • closeDrawer - 關閉
  • toggleDrawer - 切換,如果是打開則關閉,反之亦然

由於筆者沒有使用過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相關的方法

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

==》阻止多次點擊重復跳轉同一頁面

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] 可能取不到想要的值,因為還有一層數組

react-navigation的多次點擊重復跳轉同一頁面、不在堆棧路由頁面使用navigation方法的解決思路