react-navigation / react-navigation/react-navigation
React Native nested navigation unexpected behaviour
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 24.5k
- Forks
- 5.1k
- Avg merge
- 1d 5h
- Merged PRs (30d)
- 18
Description
Current behavior
I am using 'react-navigation/native' in an Expo managed project and I have built using 'react-navigation/native-stack' and 'react-navigation/bottom-tabs' a navigation structure as follows:
<Stack.Navigator screenOptions={commonHeaderStyle}>
{username && IdUser ? //If the user is not logged in its data isn't present
<Stack.Screen
name="DefaultLogged"
component={TabNavigator}
initialParams={{IdUser, username}}
options={{headerShown: false}}
/>
:
<Stack.Screen
name="DefaultHome"
component={DefaultScreen}
options={(props) => ({
headerShown: true,
header: () => (<HomeHeader navigation={props.navigation} />),
})}
/>
}
<Stack.Screen
name="Default"
component={DefaultScreen}
options={(props) => ({
headerShown: true,
header: () => (<HomeHeader navigation={props.navigation} />),
})}
/>
<Stack.Screen
name="Logged"
component={TabNavigator}
initialParams={{IdUser:null, username:null}}
options={{headerShown: false}}
/>
</Stack.Navigator>
Where the TabNavigator is the following:
<Tab.Navigator>
<Tab.Screen
name="ProfileRoot"
component={ProfileRoot}
initialParams={{IdUser, username}}
options={{title: 'Perfil', headerShown: false}}
/>
<Tab.Screen
name="WorkersRoot"
component={WorkersRoot}
options={{ title: 'Trabajadores', headerShown: false}}
/>
</Tab.Navigator>
And my ProfileRoot and WorkersRoot components are respectively:
<Stack.Navigator screenOptions={commonHeaderStyle}>
<Stack.Screen
name="Profile"
component={ProfileScreen}
options={{title: 'Perfil'}}
/>
<Stack.Screen
name="UserReviews"
component={UserReviewsScreen}
initialParams={{ category: null, IdUser, username}}
options={({ route }) => ({ title: `Reseñas de ${route.params.category}` })}
/> <Stack.Screen
name="WorkersForm"
initialParams={{IdUser, username}}
component={WorkerFormScreen}
options={{title: 'Subir oficio'}}
/>
<Stack.Screen
name="User"
component={UserScreen}
initialParams={{ IdUser: null, username: null }}
options={({ route }) => ({ title: `Perfil de ${route.params.username}`})}
/>
</Stack.Navigator>
<Stack.Navigator screenOptions={commonHeaderStyle}>
<Stack.Screen
name="WorkersCategories"
component={CategoriesScreen}
initialParams={{ type: 'trabajador' }}
options={{title: 'Encontrar trabajador' }}
/>
<Stack.Screen
name="Workers"
component={WorkersScreen}
initialParams={{ category: null }}
/>
</Stack.Navigator>
My main issue is that when I navigate to WorkersRoot and to the Workers screen, I have an action that sends me to the ProfileRoot and to the user screen with some params. Example function:
navigation.navigate('ProfileRoot', { screen: 'User', params: { IdUser: worker.id_user, username: worker.username }})
And when I hit the return button or press the Tab icon to send me to the first screen in the ProfileRoot stack I get correctly sent to that screen, but when I press the icon of the WorkersRoot Tab and press again the ProfileRoot Tab (to return to the Profile screen as expected, the User screen gets rendered instead. So once I have navigated to the User's screen from the WorkersRoot Tab, it seems there is no way to discard this screen from the ProfileRoot stack.
Here is a link to a video showing the bug
What I've tried:
-To reset navigation using dispatch every time one gets redirected to the ProfileRoot from the WorkersRoot
I could not reproduce the bug on Snack. I am currently reproducing it on a repo.
Expected behavior
Expected behaviour: navigate correctly between Tabs and the stack should be resetted
Reproduction
Platform
- Android
- iOS
- Web
- Windows
- MacOS
Packages
- @react-navigation/bottom-tabs
- @react-navigation/drawer
- @react-navigation/material-top-tabs
- @react-navigation/stack
- @react-navigation/native-stack
- react-native-tab-view
Environment
- [] I've removed the packages that I don't use
| package | version |
|---|---|
| @react-navigation/native | "^6.1.18" |
| @react-navigation/bottom-tabs | "^6.6.1" |
| @react-navigation/native-stack | "^6.9.26" |
| react-native-safe-area-context | "4.10.5" |
| react-native-screens | "^3.31.1" |
| react-native | "0.74.3" |
| expo | "~51.0.22" |
| node | "20.11.1" |
| npm or yarn | "10.2.4" |
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the linked rn-minimum reproduction and the navigation.navigate('ProfileRoot', ...) call; inspect the nested tab and native-stack state transitions when switching tabs. Confirm the expected reset behavior on Android and iOS, then isolate a minimal reproducible case or failing test showing whether the User screen remains in the ProfileRoot stack.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- react-native, typescript
- Domain
- mobile
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 32/100