It's more involved than you would hope, but I've gotten something working by creating a custom tab bar component:
const CustomTabBar = ({
state,
navigation,
descriptors,
screenHiddenInTabs,
}) => {
return (
<View
style={{
position: 'absolute',
width: '100%',
height: '100%',
}}>
<TouchableOpacity
onPress={() => {
navigation.navigate(state.routes[0].name);
}}
style={{
position: 'absolute',
height: 30,
width: '100%',
justifyContent: 'center',
backgroundColor: 'white',
}}>
<Text style={{ padding: 5 }}>{'\u003c Back to Home'}</Text>
</TouchableOpacity>
<View
style={{
flexDirection: 'row',
backgroundColor: 'white',
height: 30,
justifyContent: 'space-around',
alignItems: 'center',
position: 'absolute',
width: '100%',
bottom: 0,
}}>
{state.routes.map((route, index) => {
const isFocused = state.index === index;
const { options } = descriptors[route.key];
const label =
options.tabBarLabel !== undefined
? options.tabBarLabel
: options.title !== undefined
? options.title
: route.name;
const onPress = () => {
const event = navigation.emit({
type: 'tabPress',
target: route.key,
});
if (!isFocused && !event.defaultPrevented) {
navigation.navigate(route.name);
}
};
return route.name !== screenHiddenInTabs ? (
<TouchableWithoutFeedback onPress={onPress}>
<Text style={{ color: isFocused ? 'blue' : 'black' }}>
{label}
</Text>
</TouchableWithoutFeedback>
) : null;
})}
</View>
</View>
);
};
// Pass the CustomTabBar component to the tabBar property
function YourTabs() {
return (
<Tab.Navigator
tabBar={(props) => <CustomTabBar {...props} screenHiddenInTabs="Home" />}>
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="Browse" component={BrowseScreen} />
<Tab.Screen name="Settings" component={SettingsScreen} />
</Tab.Navigator>
);
}
The idea here is that we don't render a tab in the tab bar for a route in the tab navigator where the route name is equal to the value of the screenHiddenInTabs
prop we've added.
This way if we set the screenHiddenInTabs
prop to "Home"
, the screen in the tab navigator associated with that route name shows up on first render, but doesn't show up as a tab on the tab bar.
This custom tab bar also implements the top bar that allows you to go back to the first screen in the tab navigator, the home screen in your case.
Do take into account that because I've used absolute positioning in order to place a bar on the top and on the button, you might need extra margin to the screens inside the tab navigator.
I've used the custom tab bar in this answer: Custom Tab Bar React Navigation 5 as a template for the custom tab bar I've created above. I recommend looking at the answer there, because I've stripped some of the functionalities from that bar in order to make the example code less verbose.