React Navigation 2:如何检查上一个场景并禁用选项卡更改

时间:2018-10-26 12:45:36

标签: javascript reactjs react-native react-navigation

我有一个标签导航。我的一个标签中有一个表单,如果我的表单数据未保存,我想禁用导航事件。

在第1版中,tabBarOnPress方法提供了previousScenescenejumpToIndex,因此我能够检查我要离开哪个场景并访问其道具。

现在在版本2中,tabBarOnPress方法为场景提供了navigation道具,但是缺少了先前的场景道具:/

navigationOptions: {
    tabBarOnPress: ({ navigation, defaultHandler }) => {
        // Check the previous screen
        // If I am leaving the home screen and the user has unsaved data
        // disable tab navigation
        // else change to the pressed tab
    },
},

我还尝试了使用导航事件侦听器,但是已经调度了NAVIGATE操作:

props.navigation.addListener('willBlur', () => {
    // Disable tab switching;
}),

简单的零食:https://snack.expo.io/@hristoeftimov/handle-tab-changes-in-react-navigation-v2

任何解决方案如何在离开标签前禁用标签切换?

2 个答案:

答案 0 :(得分:1)

我发现使用getStateForAction更简单。

const defaultGetStateForAction = MainStack.router.getStateForAction;
MainStack.router.getStateForAction = (action, state) => {
    if (!state) {
        return defaultGetStateForAction(action, state);
    }

    if (
        action.type === NavigationActions.NAVIGATE
        && state.routes[state.index].key === 'HomeTab'
    ) {
        const tab = state.routes[state.index];
        const currentRoute = tab.routes[tab.index];
        const currentRouteParams = currentRoute.params;

        if (currentRouteParams && currentRouteParams.isNavigationDisabled) {
            return currentRouteParams.showConfirmationDialog(action);
        }
    }

    return defaultGetStateForAction(action, state);
}

每次在选项卡之间切换时,它都会跳到getStateForAction中,在那里我可以访问离开选项卡(从state)和下一个屏幕(从action)。

因此,当我的操作为NAVIGATE并且离开屏幕/路线为HoneTab时,我可以更改/禁用操作的默认状态并触发showConfirmationDialog()-此功能可以我可以将路由参数设置为HomeTab屏幕。

答案 1 :(得分:0)

navigation对象包含您需要的数据,因为它在导航到新选项卡之前保留导航状态。此导航状态同时包含您要导航的屏幕及其参数。

要获取状态,可以使用以下功能:

function getCurrentRoute(navState) {
  if (!navState) {
    return null;
  }
  const route = navState.routes[navState.index];

  if (route.routes) {
    return getCurrentRoute(route); // nested routes
  } else {
    return {
      name: route.routeName,
      params: { ...route.params }
    };
  }
}

因此,现在您可以在onPress处理程序中使用此函数。像这样:

navigationOptions: {
    tabBarOnPress: ({ navigation, defaultHandler }) => {
        const currentRoute = getCurrentRoute(navigation.state);
        if (currentRoute.name !== 'Home' || !currentRoute.params.isNavigationDisabled) {
            defaultHandler();
        }
    }
}

当然,这意味着您需要使用isNavigationDisabled方法在主屏幕中管理名为this.props.navigation.setParams的导航参数。

此外,我希望我的屏幕名称正确,即使不是调试它。