wake-up-neo.com

Reagieren Sie Navigation 2: So überprüfen Sie die vorherige Szene und deaktivieren Sie den Tabulatorwechsel

Ich habe eine Tabulatornavigation. Eine meiner Registerkarten hat ein Formular, und ich möchte das Navigationsereignis deaktivieren, wenn meine Formulardaten nicht gespeichert werden.

In Version 1 enthält die tabBarOnPress-Methode previousScene, scene und jumpToIndex, sodass ich überprüfen konnte, welche Szene ich verlasse, und auf deren Requisiten zugreifen kann. 

In Version 2 stellt die tabBarOnPress-Methode die navigation-Requisiten für die Szene bereit, aber die vorherige Szenenreferenz fehlt: /

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
    },
},

Ich habe es auch mit den Listenern für Navigationsereignisse versucht, aber die NAVIGATE-Aktion ist bereits ausgelöst:

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

Einfacher Snack: https://snack.expo.io/@hristoeftimov/handle-tab-changes-in-react-navigation-v2

Gibt es Lösungen, wie Sie die Tab-Umschaltung deaktivieren, bevor Sie eine Registerkarte verlassen?

9
Hristo Eftimov

Ich habe einen viel einfacheren Weg gefunden, die getStateForAction zu verwenden.

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);
}

Jedes Mal, wenn ich zwischen den Registerkarten umschalte, springt es in getStateForAction, wo ich auf die Tabulatortaste (von state) und den nächsten Bildschirm (von action) zugreifen kann.

Wenn meine Aktion also NAVIGATE ist und der Bildschirm/die Route verlassen wird, HoneTab, kann ich den Standardstatus für die Aktion ändern/deaktivieren und showConfirmationDialog() auslösen. Dies ist eine Funktion, die ich als Routenparameter für meinen HomeTab-Bildschirm festlegen kann.

0
Hristo Eftimov

Das navigation-Objekt enthält die Daten, die Sie benötigen, da es den Navigationsstatus vor der Navigation zur neuen Registerkarte enthält. Dieser Navigationsstatus hat sowohl den Bildschirm, von dem aus Sie navigieren, als auch dessen Parameter.

Um den Status zu erhalten, können Sie folgende Funktion verwenden:

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 }
    };
  }
}

Nun können Sie diese Funktion im onPress-Handler verwenden. Etwas wie das:

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

Dies bedeutet natürlich, dass Sie einen Navigationsparameter namens isNavigationDisabled auf Ihrem Startbildschirm mit der this.props.navigation.setParams-Methode verwalten müssen.

Ich hoffe auch, dass ich mit dem Bildschirmnamen richtig war, wenn nicht einfach nur debuggen.

0
Asaf David