I have a navigation structure set up as below:
- Tab 1
- Screen 1 (Initial Page)
- Screen 2
- Tab 2
- Screen 3 (Initial Page)
- Screen 4
Scenario: There will be cases when Screen 1 has to directly navigate to Screen 4. What I wanted to do is to go back from Screen 4 back to Screen 1, and when I navigate back to Tab 2 by clicking on the tab buttons, it should show me Screen 3.
Steps:
Triggered a navigation from Screen 1 to 4, works totally fine:
this.props.navigation.navigate("Tab 2", { screen: "Screen 4", initial: false, params: {...some params} })Triggered a goBack function on Screen 4, which redirects back to Screen 3, which is fine:
goBack() { this.props.navigation.goBack(); }Click on Tab 1 and redirect back to Screen 1. Works fine.
Problem occurs: Click on Tab 2, but showing Screen 4, which I want it to be showing Screen 3.
I looked up on other posts saying that one way is to reset the stack actions or something like that but I couldn't a hang of it.
Versions:
"@react-navigation/bottom-tabs": "^6.3.1",
"@react-navigation/drawer": "^6.4.3",
"@react-navigation/native": "^6.0.13",
"@react-navigation/native-stack": "^6.6.2",
"@react-navigation/stack": "^6.2.1",
Update
Found this reference on the internet and got it working. (https://www.reactnativeschool.com/reset-stack-inside-tab-after-leaving-tab)
v6 seems does not support dangerouslyGetState() function, and replaced with getState() instead.
- Create a function like below
TabPressListener = ({ navigation, route }: any) => ({
tabPress: (e: any) => {
const state = navigation.getState();
if (state) {
// Grab all the tabs that are NOT the one we just pressed
const nonTargetTabs = state.routes.filter((r: any) => r.key !== e.target);
nonTargetTabs.forEach((tab: any) => {
// Grab the key of the nested stack
const stackKey = tab?.state?.key;
// Pass the stack key that we want to reset and use popToTop to reset it
navigation.dispatch({
...StackActions.popToTop(),
target: stackKey,
});
});
}
}
})
- On the Tab.Screen component, add property "listener" which reference the above function.
<Tab.Screen
name={'Tab 1'}
listener={this.TabPressListener}
>
{...}
</Tab.Screen>
<Tab.Screen
name={'Tab 2'}
listener={this.TabPressListener}
>
{...}
</Tab.Screen>
Previously I had the flag "unmountOnBlur" set to TRUE. And ever since I commented this line of setting (which then defaults to FALSE) together with triggering the function on Step 1, the stack under each tab is reseting whenever exiting.
Hope this helps for those who got stuck on the same issue.