Tool :
I'm using Expo Router.
Current Logic :
I have a drawer navigator which contains several routes, from which i have a "users" route which contains a Stack Navigator. At first a users list get shown when navigating to users. Then you can click on a user to navigate to users detail. In this route i do hide the drawer navigator header and only show the stack with the back button. While navigating back to users route, i do show drawer navigator header again.
Problem : When navigating back there is a delay on the header display. It takes some milliseconds to show back again.
Demo : Video of Behavior
Code Snippets :
Drawer Layout :
export default function DrawerLayout() {
const shoudShow = true;
return (
<Drawer
drawerContent={(props) => <CustomDrawerContent {...props} />}
screenOptions={{
headerStyle: {
backgroundColor: '#3084dc',
},
headerShown:true,
headerTitleStyle:{fontWeight:800,fontSize:20},
headerTitleAlign:'left',
headerTintColor: '#fff',
drawerActiveTintColor:'#fff',
drawerActiveBackgroundColor:'#3084dc',
drawerInactiveTintColor:'#3084dc',
drawerItemStyle : {borderRadius : 8,marginBottom : 7},
headerRight : ({tintColor})=>{return <View style={{flexDirection:'row'}}>
<IconButton
icon="bell-outline"
iconColor={tintColor}
size={24}
rippleColor='#0000'
/>
<IconButton
icon="account-outline"
iconColor={tintColor}
size={24}
rippleColor='#0000'
/>
</View>}
}}
>
<Drawer.Screen name="(tabs)" options={{ title: 'Home', drawerIcon: ({ color,size }) => (
<Ionicons name="home" size={size} color={color} />
), }} />
<Drawer.Screen
name="profile"
options={{
title: 'Profile',
drawerIcon: ({ color,size }) => (
<Ionicons name="person" size={size} color={color} />
),
}}
/>
<Drawer.Screen
name="users"
options={{
title: 'Users',
headerStyle:{backgroundColor:'white',borderBottomWidth:0},
headerTintColor:'black',
headerShown:true,
drawerIcon: ({ color,size }) => (
<Ionicons name="people" size={size} color={color} />
),
}}
/>
<Drawer.Screen
name="settings"
options={{
title: 'Settings',
headerStyle:{backgroundColor:'white',borderBottomWidth:0},
headerTintColor:'black',
drawerIcon: ({ color,size }) => (
<Ionicons name="settings" size={size} color={color} />
),
}}
/>
<Drawer.Screen
name="references"
options={{
headerStyle:{backgroundColor:'white',borderBottomWidth:0},
headerTintColor:'black',
headerShown:true,
title: 'References',
drawerIcon: ({ color,size }) => (
<Ionicons name="person" size={size} color={color} />
),
}}
/>
</Drawer>
);
}
Users Layout :
export default function UsersLayout(){
return <Stack screenOptions={{
headerShown : false
}}>
<Stack.Screen name="index" options={{title:'Users'}}/>
<Stack.Screen name="[userId]" options={{title:'User Details',headerShown:true}}/>
</Stack>
}
[userId] route (In which the drawer header should be hidden):
export default function UserDetails(){
let shownComponent = <UserInformations/>
const [segmentValue,setSegmentValue] = useState('informations');
const navigation = useNavigation();
useLayoutEffect(() => {
navigation.getParent()?.setOptions({
headerShown: false,
});
return () =>
{
navigation.getParent()?.setOptions({
headerShown: true,
})};
}, [navigation]);
switch(segmentValue){
case 'informations':
shownComponent = <UserInformations/>;
break;
case 'activity':
shownComponent = <UserActivity/>
break;
case 'permissions':
shownComponent = <UserPermissions/>
}
return (
<ThemedView style={styles.root}>
<UserCard left={()=><ThemedView lightColor="#ffff" style={{flex:1,alignItems:'center',justifyContent:'center'}}>
<Avatar.Image size={60} source ={{uri : 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRVWT916ZIZzh7ZTuRB9cq3yVWptueIy-eKYw&s'}} />
<ThemedText style={{fontWeight:800,color : '#969696',marginTop : 6,textAlign:'center',fontSize:12}}>Admin</ThemedText>
</ThemedView>}
content={()=><ThemedView lightColor="#ffff" style={{flex:1}}>
<ThemedText style={{fontSize:18}}>John Doe</ThemedText>
<ThemedText style={{fontSize:13,color : '#969696'}}>johndoe@gmail.com</ThemedText>
<ThemedView style={[styles.description,{flexDirection:'row',justifyContent:'space-between',marginTop : 8}]}>
<ThemedView style={[styles.description,{flexDirection:'row',alignItems:'center'}]}>
<Ionicons name='ellipse' size={12} color='#008000'/>
<ThemedText style={{fontSize : 12}}> Active</ThemedText>
</ThemedView>
<ThemedText style={{fontSize : 12,paddingTop:-18}}>2hrs ago</ThemedText>
</ThemedView>
</ThemedView>}
right={(props:any) => <List.Icon icon="chevron-right"/>}
/>
<Button mode='contained' style={{backgroundColor:'#3084dc',marginTop : 20,borderRadius:8}}>Reset Password</Button>
<SegmentedButtons
value={segmentValue}
onValueChange={setSegmentValue}
style={styles.segmentContainer}
theme={{ roundness: 0 }}
buttons={[
{
labelStyle:{fontWeight:800,fontSize:13},
checkedColor:'#3084dc',
uncheckedColor:'#3084dc',
value: 'informations',
label: 'Informations',
style: [styles.segmentButton,{borderBottomColor:segmentValue=='informations'?'#3084dc':'#E1E1E1'}],
},
{
labelStyle:{fontWeight:800,fontSize:13},
checkedColor:'#3084dc',
uncheckedColor:'#3084dc',
value: 'activity',
label: 'Activity',
style: [styles.segmentButton,{borderBottomColor:segmentValue=='activity'?'#3084dc':'#E1E1E1'}]
},
{
labelStyle:{fontWeight:800,fontSize:13},
checkedColor:'#3084dc',
uncheckedColor:'#3084dc',
value: 'permissions',
label: 'Permissions',
style: [styles.segmentButton,{borderBottomColor:segmentValue=='permissions'?'#3084dc':'#E1E1E1'}]
},
]}
/>
<ThemedView style={styles.segmentsContent}>
{shownComponent}
</ThemedView>
</ThemedView>
);
}
Finally i've managed to solve this by hiding the stack navigator header once and for all. Then i implemented the content of the drawer header based on the current route, hence showing a back button inside the [userid] route