Cómo restablecer TabNavigator cuando el usuario cierra la sesión (desde otra pantalla)

Aquí está mi jerarquía de archivos de proyecto

RootTabNavigator | AuthStackNavigator // I want to go back to this navigator | AuthoScreen | Welcome Screen | MainTabNavigator // I want to reset MainTabNavigator | FeedStacknavigator | Screen A | OtherStackNavigatorOne | Screen E | OtherStackNavigatorTwo | Screen D | MenuStackNavigator | Menuo <-I'm here and want to reset to 'MainTabNavigator' and go BACK to 'AuthScreen' | Screen B | Screen C 

Problema

El usuario se encuentra en la pantalla Menuo en MenuStackNavigator y MainTabNavigator.

Si el usuario no tiene un token (cuando el usuario cierra la sesión), el usuario vuelve a la pantalla de autenticación.

Pero al mismo tiempo quiero RESETEAR MainTabNavigator . Puede desmontar, realizar NavigationActions.init () o lo que sea que pueda. Prefiero NavigationActions.init ()

Solo quiero configurar MainTabNavigator por primera vez.

Código

si no hay un token, vuelvo a la pantalla de autenticación (esto está funcionando)

 This code if the part of Menuo Screen componentWillReceiveProps(nextProps) { if ( nextProps.token == undefined || _.isNil(nextProps.token) ) { const backAction = NavigationActions.back({ key: null }) nextProps.navigation.dispatch(backAction); ... 

(Pregunta) ¿Cómo podemos reiniciar MainTabNavigator incluyendo Child StackNavigators?

 MainTabNavigator.js export default TabNavigator( { Feed: { screen: FeedStacknavigator, }, OtherOne: { screen: OtherStackNavigatorOne, } ... }, { navigationOptions: ({navigation}) => ){ header: null, tabBarIcon: ({focused}) => ... ... } 

Solución posible

Puedo cambiar MainTabNavigator de una función a otra y tratar de restablecer TabNavigator allí. (No estoy seguro).

Esta vez, necesito un ejemplo de trabajo concreto. He estado leyendo doc y solicitando mi aplicación, pero no pude resolver esto.

Por favor, avíseme si algo no está claro.

ACTUALIZAR

 const RootTabNavigator = TabNavigator ({ Auth: { screen: AuthStackNavigator, }, Welcome: { screen: WelcomeScreen, }, Main: { screen: MainTabNavigator, }, }, { navigationOptions: () => ({ ... } ); export default class RootNavigator extends React.Component { componentDidMount() { this._notificationSubscription = this._registerForPushNotifications(); } 

Esto debería funcionar en la mayoría de los casos:

 componentWillReceiveProps(nextProps) { if ( nextProps.token == undefined || _.isNil(nextProps.token) ) { let action = NavigationActions.reset({ index: 0, key: null, actions: [ NavigationActions.navigate({routeName: 'Auth'}) ] }); nextProps.navigation.dispatch(action); } ... } 

O intente mejorando su navegador con una acción personalizada:

 const changeAppNavigator = Navigator => { const router = Navigator.router; const defaultGetStateForAction = router.getStateForAction; router.getStateForAction = (action, state) => { if (state && action.type === "RESET_TO_AUTH") { let payLoad = { index: 0, key: null, actions: [NavigationActions.navigate({routeName: "AuthStackNavigator"})] }; return defaultGetStateForAction(NavigationActions.reset(payLoad), state); // or this might work for you, not sure: // return defaultGetStateForAction(NavigationActions.init(), state) } return defaultGetStateForAction(action, state); }; return Navigator; }; const screens = { ... } RootTabNavigator = changeAppNavigator(TabNavigator(screens, { initialRouteName: ..., ... })); 

Luego, en tu Menuo Screen haz:

 componentWillReceiveProps(nextProps) { if ( nextProps.token == undefined || _.isNil(nextProps.token) ) { nextProps.navigation.dispatch({type: "RESET_TO_AUTH"}); ... 

Puede definir una lógica de navegación personalizada extendiendo el enrutador. Para lograr lo que quiere que describió en la jerarquía de archivos del proyecto en su pregunta, puede hacer algo como esto a continuación.

MainTabNavigator.js

 ... RootTabNavigator.router.getStateForAction = (action, state) => { if (state && action.type === 'GoToAuthScreen') { return { ...state, index: 0, }; } return RootTabNavigator.router.getStateForAction(action, state); }; MainTabNavigator.router.getStateForAction = (action, state) => { if (state && action.type === 'GoToAuthScreen') { return { ...state, index: 0, }; } return MainTabNavigator.router.getStateForAction(action, state); }; MenuStackNavigator.router.getStateForAction = (action, state) => { if (state && action.type === 'GoToAuthScreen') { return { ...state, index: 0, }; } return MenuStackNavigator.router.getStateForAction(action, state); }; 

En el archivo Menuo Screen

 componentWillReceiveProps(nextProps) { if ( nextProps.token == undefined || _.isNil(nextProps.token) ) { const goToAuthScreen = () => ({ type: 'GoToAuthScreen', }); nextProps.navigation.dispatch(goToAuthScreen); ... } } 

Lo que necesita es inicializar el navegador al estado inicial. Puede hacerlo con NavigationActions.init() . Puede obtener más información sobre las acciones de navegación aquí .

Puede hacer esto creando una acción de navegación personalizada, lea más sobre ellos aquí .

Aquí hay un código que lo haría por usted:

 // First get a hold of your navigator const navigator = ... // Get the original handler const defaultGetStateForAction = navigator.router.getStateForAction // Then hook into the router handler navigator.router.getStateForAction = (action, state) => { if (action.type === 'MyCompleteReset') { // For your custom action, reset it all return defaultGetStateForAction(NavigationActions.init()) } // Handle all other actions with the default handler return defaultGetStateForAction(action, state) } 

Para activar su acción de navegación personalizada, debe enviarla de la siguiente manera desde su componente Reaccionar:

  this.props.navigation.dispatch({ type: "MyCompleteReset", index: 0 })