How to reset TabNavigator when user logs out (from other screen)

后端 未结 3 1069
心在旅途
心在旅途 2020-11-27 19:49

Here is my project file hierarchy

RootTabNavigator
    | AuthStackNavigator // I want to go back to this navigator
          | AuthoScreen
    | Welcome Scre         


        
相关标签:
3条回答
  • 2020-11-27 20:18

    What you need is to initialize the navigator to the initial state. You can do that with NavigationActions.init(). You can learn more about Navigations Actions here.

    You can do this by creating a Custom Navigation Action, read more about them here.

    Here's some code that would do that for you:

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

    In order to trigger your Custom Navigation Action, you have to dispatch it as follows from within your React Component:

      this.props.navigation.dispatch({
          type: "MyCompleteReset",
          index: 0
        })
    
    0 讨论(0)
  • 2020-11-27 20:24

    You can define custom navigation logic by extending the router. To accomplish what you want that you described in the project file hierarchy in your question you can do something like this below.

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

    In the Menuo Screen file

    componentWillReceiveProps(nextProps) {
      if ( nextProps.token == undefined || _.isNil(nextProps.token) ) {
        const goToAuthScreen = () => ({
          type: 'GoToAuthScreen',
        });
    
        nextProps.navigation.dispatch(goToAuthScreen);
        ...
      }
    }
    
    0 讨论(0)
  • 2020-11-27 20:41

    This should work in most cases:

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

    Or try by enhancing your navigator with custom action:

    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: ...,
      ...
    }));
    

    Then in your Menuo Screen do:

    componentWillReceiveProps(nextProps) {
        if ( nextProps.token == undefined || _.isNil(nextProps.token) ) {
    
            nextProps.navigation.dispatch({type: "RESET_TO_AUTH"});
        ...
    
    0 讨论(0)
提交回复
热议问题