Here is my project file hierarchy
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
The user is on Menuo Screen under MenuStackNavigator and MainTabNavigator.
If user doesn't have a token (when user logs out), user goes back to the Auth Screen.
But at the same time I want to RESET MainTabNavigator. You can unmount , perform NavigationActions.init() or whatever you can. I prefer NavigationActions.init()
I just want to set MainTabNavigator to its very first time.
if there is no token, I go back to Auth Screen (This is working)
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);
...
(Question) How can we reset MainTabNavigator including child StackNavigators?
MainTabNavigator.js
export default TabNavigator(
{
Feed: {
screen: FeedStacknavigator,
},
OtherOne: {
screen: OtherStackNavigatorOne,
}
...
}, {
navigationOptions: ({navigation}) => ){
header: null,
tabBarIcon: ({focused}) => ...
...
}
I can maybe change MainTabNavigator from function to class and deal with resetting TabNavigator there. (I'm not sure).
This time, I need a concrete working example. I've been reading doc and applying to my app but I couldn't solve this.
Please let me know if anything is unclear.
UPDATE
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();
}
If you want every stack to reset when changing tabs you can remove the tabName === TAB_TO_RESET check. Learn all you need about React Navigation with our Master React Navigation v5 course!
navigate({ routeName: 'Tab', action: NavigationActions. navigate({ routeName: 'Market', }), }), ], });
You can go back to an existing screen in the stack with navigation. navigate('RouteName') , and you can go back to the first screen in the stack with navigation. popToTop() .
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"});
...
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
})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With