Reputation: 21
I have nested navigators i.e a stack navigator within a stack navigator.
when naming the nested navigator the individual routes don't get their proper name but they get the name of the parent.
(i.e when I go move to main screen the title remains login/signup)
How do I solve this?
export default function App() {
return (
<NavigationContainer>
<Stack.Navigator>
{/* <Stack.Screen name="HomeScreen" component={HomeScreen} />
<Stack.Screen
name="DisclaimerScreen"
component={DisclaimerScreen}
options={{headerLeft: null}}
/>
<Stack.Screen name="Name Screen" component={NameScreen} />
<Stack.Screen name="Date Screen" component={DateScreen} />
<Stack.Screen name="GenderScreen" component={GenderScreen} />
<Stack.Screen name="InfoScreen" component={InfoScreen} /> */}
<Stack.Screen name="Login/Signup" component={Login} />
</Stack.Navigator>
</NavigationContainer>
);
}
function Login() {
return (
<LoginStack.Navigator headerTitle="Login">
<LoginStack.Screen
name="UsernameScreen"
options={{title: 'Signup'}}
component={UsernameScreen}
/>
{/* TODO: ADD another screen for loggin in */}
<LoginStack.Screen name="LoginScreen" component={LoginScreen} />
<LoginStack.Screen
name="MainScreen"
options={{title: 'Home'}}
component={Main}
/>
</LoginStack.Navigator>
);
}
Upvotes: 0
Views: 366
Reputation: 15462
The reason it's not working is because you're trying to change a parent navigator's options inside a child navigator. First you don't need to set the title in options
prop in the Login
component for what you're trying to do:
function Login() {
return (
<LoginStack.Navigator>
<LoginStack.Screen
name="UsernameScreen"
component={UsernameScreen}
/>
{/* TODO: ADD another screen for loggin in */}
<LoginStack.Screen name="LoginScreen" component={LoginScreen} />
<LoginStack.Screen
name="MainScreen"
component={Main}
/>
</LoginStack.Navigator>
);
}
Then you can create a function to handle how the parent header title should change based on the child:
function getHeaderTitle(route) {
// If the focused route is not found, we need to assume it's the initial screen
// This can happen during if there hasn't been any navigation inside the screen
const routeName = getFocusedRouteNameFromRoute(route) ?? 'UsernameScreen';
switch (routeName) {
case 'UsernameScreen':
return 'Signup'
case 'MainScreen':
return 'Home';
// etc...
}
}
Then you can use the function in your parent stack navigator like this:
// ...
<Stack.Navigator>
<Stack.Screen
name="Login/Signup"
component={Login}
options={({ route }) => ({
headerTitle: getHeaderTitle(route),
})}
/>
// ...
</Stack.Navigator>
// ...
This approach is described very well in the documentation here: https://reactnavigation.org/docs/screen-options-resolution/#setting-parent-screen-options-based-on-child-navigators-state.
Be sure to import getFocusedRouteNameFromRoute from @react-navigation/native.
Upvotes: 1