React navigation initialRouteName property not working as expected - react-native

In my react native app I nested stack navigation inside the tab navigation.
I can't access the screen that I set as an initial route in stack navigation.
The tab navigation component is
<Tab.Navigator initialRouteName='HomeNav' >
<Tab.Screen name="HomeNav" component={HomeNav}
options={{
tabBarIcon: ({ color, size }) => (
<FIcon name="home" color={color} size={size} />
),
}}
/>
<Tab.Screen name="Search" component={Search}
options={{
tabBarIcon: ({ color, size }) => (
<FIcon name="search" color={color} size={size} />
)
}}
/>
<Tab.Screen name="Cart" component={Cart}
options={{
tabBarIcon: ({ color, size }) => (
<MCIcon2 name="cart" color={color} size={size} />
)
}}
/>
<Tab.Screen name="AccountNav" component={AccountNav}
options={{
tabBarIcon: ({ color, size }) => (
<MCIcon2 name="account" color={color} size={size} />
)
}}
/>
</Tab.Navigator >
And here is the account navigation component
const AccountNav = () => {
return (
<Stack.Navigator
initialRouteName="Account"
screenOptions={{
headerShown: false
}}
>
<Stack.Screen name="Account" component={Account} />
<Stack.Screen name="MyOrders" component={MyOrders} />
<Stack.Screen name="Profile" component={Profile} />
</Stack.Navigator>
);
when I try to navigate to MyOrders screen from the other screens. it gets stuck and cannot access the initial route screen (Account).

I had this issue aswell, I solved it by adding lazy: false to the tab navigators screenOptions prop.
screenOptions={{
headerShown: false,
lazy: false
}}
Documentation says that "Routes are lazily initialized -- their screen components are not mounted until they are first focused.", my guess is that the initial route you specify won't "register" until the screen's components are properly mounted (until the screen is focused), so when you go to your AccountNav, the initial route becomes the one you navigated too, bypassing the prop.
The issue with this is that you're mounting all the screen components from all the screens and that may impact performance depending on your application I guess

Related

React Native Tab Navigator

I am totally new to React Native and I am currently trying show BottomTabNavigator on child/details page, for example:
I have a page called Training and I have another page called TrainingDetails.
I wanna show BottomTabNavigator on TrainingDetails.
On truth, I wanna show BottomTabNavigator in all pages, main pages and detail pages.
Here is my Main.js
Thanks so much!
const Tab = createBottomTabNavigator();
return (
<Tab.Navigator tabBarOptions={{ activeTintColor: theme.colors.primary, inactiveTintColor: theme.colors.neutral_100, style: {backgroundColor: theme.colors.active} }}>
<Tab.Screen
options={{
title: "Trabalhar",
tabBarIcon: ({ focused, color, size }) => (
<MaterialIcon name={"headset"} size={size} color={color} />
),
}}
name="Home"
component={HomeScreen}
/>
<Tab.Screen
options={{
title: "Estudar",
tabBarIcon: ({ focused, color, size }) => (
<SimpleLineIcon name={"graduation"} size={size} color={color} />
),
}}
name="Study"
component={Training}
/>
<Tab.Screen
options={{
title: "Notificações",
tabBarIcon: ({ focused, color, size }) => (
<MaterialIcon name={"bell-outline"} size={size} color={color} />
),
}}
name="Notification"
component={HomeScreen}
/>
<Tab.Screen
options={{
title: "Resultados",
tabBarIcon: ({ focused, color, size }) => (
<MaterialIcon name={"trending-up"} size={size} color={color} />
),
}}
name="Results"
component={HomeScreen}
/>
<Tab.Screen
options={{
title: "Carteira",
tabBarIcon: ({ focused, color, size }) => (
<MaterialIcon name={"wallet-outline"} size={size} color={color} />
),
}}
name="Wallet"
component={HomeScreen}
/>
</Tab.Navigator>
);
};
export default Main;
You can put a stackNavigator inside a tab navigator, so for example if you want a home screen and then another screen called details that doesn't have a tab at the bottom but still has the tabs at the bottom you can replace the home screen with a homeStack that has both a home screen and details screen inside it.
const Stack = createStackNavigator();
function HomeStack() {
return (
<Stack.Navigator>
<Stack.Screen name="Home" component={Home} />
<Stack.Screen name="Details" component={Details} />
</Stack.Navigator>
);
}
and then replace your home component in the tab navigator with HomeStack component.

Always show BottomTabNavigation

How can I show BottomTabNavigation even on stacked screen? I have tried this for a few hours but really don't get it to work as expected.
So the thing I want to happen is, if I navigate to say for example the Title Screen, I still want to show the BottomTabNavigation. Any suggestions?
I can of course create a new navigation, but then it is sliding in from the side.
const Stack = createStackNavigator();
const Tab = createBottomTabNavigator();
const HomeTabNavigator = () => {
return (
<Tab.Navigator
tabBarOptions={{
labelStyle: {textTransform: 'uppercase'},
style: {
backgroundColor: '#111111', //Färger på footerbar
borderTopColor: 'transparent',
borderBottomColor: 'transparent',
},
}}>
<Tab.Screen
name={'Concerts'}
component={ConcertsScreen}
options={{
tabBarIcon: ({tintColor}) => (
<Image
source={require('../../assets/icons/concerts.png')}
size={25}
/>
),
}}
/>
<Tab.Screen
name={'Docs'}
component={DocumentiesScreen}
options={{
tabBarIcon: ({tintColor}) => (
<Image source={require('../../assets/icons/docs.png')} size={25} />
),
}}
/>
<Tab.Screen
name={'Profile'}
component={ProfileScreen}
options={{
tabBarIcon: ({tintColor}) => (
<Image source={require('../../assets/icons/user.png')} size={25} />
),
}}
/>
</Tab.Navigator>
);
};
const Router = () => {
const {token, setToken} = useContext(TokenContext);
const {userFav, addFav, getFav} = useContext(UserContext);
const [isLoading, setLoading] = useState(true);
useEffect(() => {
setLoading(false);
setTimeout(() => {}, 1000);
}, []);
return (
<NavigationContainer>
{token ? (
<Stack.Navigator
initialRouteName="Home"
screenOptions={{
headerTransparent: true,
noBorder: true,
}}
headerMode="float">
<Stack.Screen name={' '} component={HomeTabNavigator} />
<Stack.Screen name={'Concerts'} component={ConcertsScreen} />
<Stack.Screen name={'User Profile'} component={ProfileScreen} />
<Stack.Screen
name={'FavouritesScreen'}
component={FavouritesScreen}
/>
<Stack.Screen name={'Docs'} component={DocumentiesScreen} />
<Stack.Screen name={'AccountScreen'} component={AccountScreen} />
<Stack.Screen name={'Home of'} component={SearchScreen} />
<Stack.Screen name={'Artist'} component={ArtistScreen} />
<Stack.Screen name={'Title'} component={Videos} />
<Stack.Screen name={'PlayVideo'} component={PlayVideo} />
</Stack.Navigator>
) : (
<LoginScreen />
)}
</NavigationContainer>
);
};
You need to nest all your stack screens inside a tab screen.
The BottomTabNavigator disappear because you leave your Tab.Navigator component.
I hope this helps. If you want to navigate between screens that are related to a specific tab button, and have that tab button remain active while moving between these screens, you should set up a StackNavigation within that tab's component. By doing so, the tab button will remain active while navigating within its related screens.
On the other hand, if you want the TabNavigation to be visible throughout the whole application but some screens should not be displayed as tabs, you can add all screens inside the TabNavigation and specify in the options for those screens not to be displayed as tab buttons. That way, while in the screen without a tab button, the tabs will still be visible but none will be active. For example, you can do this for a screen called 'Title':
<Tab.Screen
name={'Title'}
component={Videos}
options={{
tabBarIcon: ({tintColor}) => (
<Image source={require('../../assets/icons/user.png')} size={25} />
),
tabBarButton: () => null <---- *this causes it to have no button*
}}
/>
I hope this helps!

react-navigation: header above tab nav

I'm trying to get the Recipes header in the following image to display above the tab navigator (home and settings in the image below). Currently I have the tab navigator in a stack navigator. On the stack navigator I defined a title and headerTitle but neither are displaying. How can I get the header above? Thanks!
This is what it looks like currently:
I want to achieve something similar to this:
This is my stack nav code:
<NavigationContainer>
<Tab.Navigator
shifting={false}
labeled={false}
initialRouteName="Home"
activeColor="#32CA81"
barStyle={styles.navContainer}
screenOptions={{
headerShown: false,
}}
tabBarOptions={{
activeTintColor: '#e91e63',
}}
>
<Tab.Screen
name="Camera"
component={Camera}
options={{
tabBarLabel: "Camera",
tabBarIcon: ({ color }) => (
<MaterialIcons name="camera-alt" color={color} size={26} />
),
}}
/>
<Tab.Screen
name="Home"
component={Home}
options={{
title: "Recipes",
headerTitle: "Recipes",
tabBarLabel: "Recipes",
tabBarIcon: ({ color }) => (
<MaterialIcons name="restaurant-menu" color={color} size={26} />
),
}}
/>
<Tab.Screen
name='Saved'
component={SavedScreen}
options={{
shifting: true,
tabBarLabel: 'Saved',
tabBarIcon: ({color}) => (
<MaterialIcons name='favorite' color={color} size={26} />
),
}}
/>
</Tab.Navigator>
</NavigationContainer>
This is my tab nav code:
return (
<Tab.Navigator>
<Tab.Screen name="Home" component={Recipes} />
<Tab.Screen name="Settings" component={Recipes} />
</Tab.Navigator>
);
I ended up wrapping the component with the tabs, with a stack navigator. I put the text component and tabs on the same stack screen.

React native i cannot add a new screen without adding it to createMaterialBottomTabNavigator

Hello i want to be able to go to a new page without adding them to <Tab.Screen by another meaning i want to use this.props.navigation.navigate so in order for me to do that i need to add the new screen but how i can add a new screen without adding them to <tab.screen
this is a small sample of my code
const Tab = createMaterialBottomTabNavigator();
const Stack = createStackNavigator();
const App = ({navigation}) => {
return (
<NavigationContainer>
<Tab.Navigator initialRouteName="Home" shifting={true}>
<Tab.Screen
name="Feed"
component={mainPage}
options={{
tabBarLabel: 'Home',
tabBarColor: '#29a8ab',
tabBarIcon: ({color}) => (
<Icon name="home" color={color} size={26} />
),
}}
tabBarColor={'#FF0000'}
/>
<Tab.Screen
name="Notifications"
component={cartPage}
options={{
tabBarLabel: 'Shop',
tabBarColor: '#ff8b94',
tabBarIcon: ({color}) => (
<Icon name="cart" color={color} size={26} />
),
}}
/>
</Tab.Navigator>
</NavigationContainer>
);
};
export default createApp;

Can't scroll with react-native-paper and #react-navigation/bottom-tabs

I have:
<PaperProvider theme={theme}>
<NavigationContainer>
<Tab.Navigator initialRouteName="Feed">
<Tab.Screen
name="Home"
component={Conversations}
options={{
tabBarLabel: "Home",
tabBarIcon: ({ color, size }) => (
<AntDesign name="home" size={size} color={color} />
),
}}
/>
<Tab.Screen
name="Explore"
component={Conversations}
options={{
tabBarLabel: "Explore",
tabBarIcon: ({ color, size }) => (
<AntDesign name="find" size={size} color={color} />
),
}}
/>
<Tab.Screen
name="Profile"
component={Conversations}
options={{
tabBarLabel: "Profile",
tabBarIcon: ({ color, size }) => (
<AntDesign name="setting" size={size} color={color} />
),
}}
/>
</Tab.Navigator>
</NavigationContainer>
</PaperProvider>;
And it loads fine, but I can't scroll. I'm also using react-native-web to attempt to make it web compatible.
It seems this is actually a problem with Expo, which I supose you are using to test your app. The problem is described in this Issue in the React Navigation repo:
https://github.com/react-navigation/react-navigation/issues/1797
Updating/Reinstalling Expo seems to fix your problem, if this is the case!
There is also an old fix for Expo's web integration that had this problem too, as described in this issue:
https://github.com/react-navigation/react-navigation/issues/6165
Theorically it is fixed, but if you are using an old version of React Navigation... Well, it seems you can fix this by setting the cardStyle property to {flex: 1}