I want to separate my navigation tabs into an isolated folder called tabs.
The first tab called HomeTab:
import React from 'react';
import {createBottomTabNavigator} from '#react-navigation/bottom-tabs';
import Icon from 'react-native-vector-icons/AntDesign';
import {Home} from '../../../screens';
const Tab = createBottomTabNavigator();
const HomeTab = () => (
<Tab.Screen
name="Home"
component={Home}
options={{
tabBarLabel: 'Home',
tabBarIcon: ({color, size}) => (
<Icon name="home" color={color} size={size} />
),
}}
/>
);
export {HomeTab};
I imported my HomeTab and nested with TabNavigator:
import * as React from 'react';
import {HomeTab} from './Tabs/Home';
import {NavigationContainer} from '#react-navigation/native';
import {createBottomTabNavigator} from '#react-navigation/bottom-tabs';
const Tab = createBottomTabNavigator();
const TabNavigation = () => (
<NavigationContainer>
<Tab.Navigator>
<HomeTab />
</Tab.Navigator>
</NavigationContainer>
);
export default TabNavigation;
But I got this error:
However, when I move the HomeTab code inside the TabNavigator, it works as expected.
const TabNavigation = () => (
<NavigationContainer>
<Tab.Navigator>
<Tab.Screen
name="Home"
component={Home}
options={{
tabBarLabel: 'Home',
tabBarIcon: ({color, size}) => (
<Icon name="home" color={color} size={size} />
),
}}
/>
</Tab.Navigator>
</NavigationContainer>
);
Direct children of any react-navigation parent must be a Group, a Screen or a Fragment, consider doing this:
const TabNavigation = () => (
<NavigationContainer>
<HomeTab />
</NavigationContainer>
);
const HomeTab = () => (
<Tab.Navigator>
<Tab.Screen
name="Home"
component={Home}
options={{
tabBarLabel: 'Home',
tabBarIcon: ({color, size}) => (
<Icon name="home" color={color} size={size} />
),
}}
/>
{* any other tab *}
</Tab.Navigator>
);
Related
This is the container file.
Here I have defined all the required details for the bottom navigation and it is rendered at the top the screen but it should be render at the bottom of the screen.
import { NavigationContainer } from "#react-navigation/native";
import MaterialCommunityIcons from "react-native-vector-icons/MaterialCommunityIcons";
import HomeScreen from "./Fragments/HomeScreen";
import WalletScreen from "./Fragments/WalletScreen";
import ProfileScreen from "./Fragments/ProfileScreen";
import { StyleSheet, View } from "react-native";
const Tab = createBottomTabNavigator();
import { Platform } from "react-native";
export const tabBarHeight = Platform.OS === "ios" ? 60 : 45;
function MyTabs() {
return (
<NavigationContainer>
<Tab.Navigator
initialRouteName="Home"
screenOptions={{
tabBarStyle: {
backgroundColor: "#03dbfc",
height: tabBarHeight,
},
tabBarActiveTintColor: "white",
}}
>
<Tab.Screen
name="Home"
component={HomeScreen}
options={{
tabBarLabel: "Home",
tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons name="home" color={color} size={size} />
),
}}
/>
<Tab.Screen
name="Wallet"
component={WalletScreen}
options={{
tabBarLabel: "Wallet",
tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons name="wallet" color={color} size={size} />
),
}}
/>
<Tab.Screen
name="Profile"
component={ProfileScreen}
options={{
tabBarLabel: "Profile",
tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons name="face" color={color} size={size} />
),
}}
/>
</Tab.Navigator>
</NavigationContainer>
);
}
export default MyTabs;
I can't see the content of each screen or fragment.
Home.js
import { Text } from "react-native";
const HomeScreen = ({ navigation }) => {
return <Text>Home</Text>;
};
export default HomeScreen;
Profile.js
import React from "react";
import { Text } from "react-native";
const ProfileScreen = ({ navigation }) => {
return <Text>Profile</Text>;
};
export default ProfileScreen;
Wallet.js
import React from "react";
import { Text } from "react-native";
const WalletScreen = ({ navigation }) => {
return <Text>Wallet</Text>;
};
export default WalletScreen;
Please answer this question I am new to react-native.
App.js
import { NavigationContainer } from "#react-navigation/native";
import Header from "./components/Header/Header";
import BottomNavigation from "./components/BottomNavigation/BottomNavigation";
export default function App() {
return (
<View>
<Header title="ApnaPayment" />
<BottomNavigation />
</View>
);
}
This problem happens because the View on App.js shrinks the page content. You don't need to create a header component, the react-navigation provides it for you. I suggest you remove the header component on App.js and add the header title as a screen option on your navigator. Another tip is you don't need to define the height of the tabs, the react-navigation provides it too by default. Follow the example code below.
File with your navigator:
// Some code above...
function MyTabs() {
return (
<NavigationContainer>
<Tab.Navigator
initialRouteName="Home"
screenOptions={{
tabBarStyle: {
backgroundColor: "#03dbfc",
},
tabBarActiveTintColor: "white",
title: "ApnaPayment",
}}
>
<Tab.Screen
name="Home"
component={HomeScreen}
options={{
tabBarLabel: "Home",
tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons name="home" color={color} size={size} />
),
}}
/>
<Tab.Screen
name="Wallet"
component={WalletScreen}
options={{
tabBarLabel: "Wallet",
tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons name="wallet" color={color} size={size} />
),
}}
/>
<Tab.Screen
name="Profile"
component={ProfileScreen}
options={{
tabBarLabel: "Profile",
tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons name="face" color={color} size={size} />
),
}}
/>
</Tab.Navigator>
</NavigationContainer>
);
}
export default MyTabs;
Your App.js:
// Some code above...
export default function App() {
return (
<BottomNavigation />
);
}
I am having a Bottom Navigation with 2 Tabs so far (Home & Messages). When inside Messages I can press on a User to get navigated to the ChatScreen which is a Screen from the Stack Navigator. In that ChatScreen I want to hide the BottomTab. I know that it is possible to hide it by adding tabBarStyle: { display: "none" } to the <Tab.Screen /> but this doesn't work for the ChatScreen since it is not a Tab.Screen
import * as React from 'react';
import {View, Text} from 'react-native';
import {NavigationContainer, StackActions} from '#react-navigation/native';
import {createNativeStackNavigator} from '#react-navigation/native-stack';
import Home from './app/Screens/Home';
import CommentSection from './app/Screens/CommentSection';
import MessageScreen from './app/Screens/MessageScreen';
import ChatScreen from './app/Screens/ChatScreen';
import NavigationHeader from './app/global/headers/NavigationHeader';
import SendOffer from './app/Screens/SendOffer';
import {createBottomTabNavigator} from '#react-navigation/bottom-tabs';
import Icon from 'react-native-vector-icons/MaterialIcons';
import ChatScreenHeader from './app/Screens/ChatScreen/ChatScreenHeader';
const HomeStack = createNativeStackNavigator();
const HomeStackScreen = () => {
return (
<HomeStack.Navigator initialRouteName="Home">
<HomeStack.Screen
name="HomeScreen"
component={Home}
options={{
// header: AppBar,
headerShown: false,
}}
/>
<HomeStack.Screen
name="CommentSection"
component={CommentSection}
options={{
headerTitle: 'Home',
// animationTypeForReplace: 'push',
animation: 'slide_from_bottom',
}}
/>
<HomeStack.Screen
name="SendOffer"
component={SendOffer}
options={{
headerTitle: 'Home',
animation: 'slide_from_right',
}}
/>
<HomeStack.Screen
name="ChatScreen"
component={ChatScreen} //HIDE BottomTab INSIDE THIS COMPONENT
options={{
headerTitle: 'Messages',
animation: 'slide_from_right',
}}
/>
</HomeStack.Navigator>
);
};
const MessageStack = createNativeStackNavigator();
const MessageStackScreen = () => {
return (
<MessageStack.Navigator>
<MessageStack.Screen
name="MessageScreen"
component={MessageScreen}
options={{
headerTitle: 'Messages',
animation: 'slide_from_right',
}}
/>
<MessageStack.Screen
name="ChatScreen"
component={ChatScreen} //HIDE BottomTab INSIDE THIS COMPONENT
options={{
headerTitle: 'Messages',
headerShown: false,
animation: 'slide_from_right',
}}
/>
</MessageStack.Navigator>
);
};
const Tab = createBottomTabNavigator();
export default function App() {
return (
<NavigationContainer>
<Tab.Navigator initialRouteName="Messages">
<Tab.Screen
name="Home"
component={HomeStackScreen}
options={{
headerShown: false,
tabBarLabel: 'Home',
tabBarIcon: ({ color }) => (
<Icon name="home" color={color} size={26} />
),
}}
/>
<Tab.Screen
name="Messages"
component={MessageStackScreen}
options={{
headerShown: false,
tabBarLabel: 'Messages',
tabBarIcon: ({ color }) => (
<Icon name="chat" color={color} size={26} />
),
// tabBarStyle: { display: "none" }
}}
/>
</Tab.Navigator>
</NavigationContainer>
);
}
Used solution by #Escaper from another question
useEffect(() => {
navigation.getParent()?.setOptions({ tabBarStyle: { display: "none" }});
return () => navigation.getParent()?.setOptions({ tabBarStyle: undefined });
}, [navigation]);
You could use createNavigationContainerRef to check the current route name via the getCurrentRoute() function inside the component that creates the BottomTabNavigator and then use tabBarStyle conditionally as you have suggested.
This could look as follows.
import { createNavigationContainerRef } from "#react-navigation/native"
const ref = createNavigationContainerRef();
const Tab = createBottomTabNavigator();
export default function App() {
const hide = "ChatScreen" === ref.current?.getCurrentRoute()?.name
return (
<NavigationContainer>
<Tab.Navigator initialRouteName="Messages">
<Tab.Screen
name="Home"
component={HomeStackScreen}
options={{
headerShown: false,
tabBarLabel: 'Home',
tabBarIcon: ({ color }) => (
<Icon name="home" color={color} size={26} />
),
}}
/>
<Tab.Screen
name="Messages"
component={MessageStackScreen}
options={{
headerShown: false,
tabBarLabel: 'Messages',
tabBarIcon: ({ color }) => (
<Icon name="chat" color={color} size={26} />
),
tabBarStyle: { display: hide ? "none" : "flex" }
}}
/>
</Tab.Navigator>
</NavigationContainer>
);
}
/* eslint-disable react-native/no-inline-styles */
/* eslint-disable prettier/prettier */
import * as React from 'react';
import Home from '../screens/home';
import Review from '../screens/reviewDetails';
import Profile from '../screens/profile';
import Settings from '../screens/settings';
import Ionicons from 'react-native-vector-icons/Ionicons';
import { COLORS, icons } from '../constants';
import { Image } from 'react-native';
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
import { createMaterialBottomTabNavigator } from '#react-navigation/material-bottom-tabs';
import {createBottomTabNavigator} from '#react-navigation/bottom-tabs';
const Tab = createMaterialBottomTabNavigator();
export default function HomeStack() {
return (
<Tab.Navigator initialRouteName="Home">
<Tab.Screen name="Home" component={Home} options={{
tabBarLabel: 'Home',
tabBarIcon: ({ color }) => (
<MaterialCommunityIcons name="home" color={color} size={26} />
),
}} />
<Tab.Screen name="Review Details" component={Review} options={{
tabBarLabel: 'Review',
tabBarIcon: ({ color }) => (
<MaterialCommunityIcons name="home" color={color} size={26} />
),
}} />
<Tab.Screen name="Profile" component={Profile} options={{
tabBarLabel: 'Profile',
tabBarIcon: ({ color }) => (
<MaterialCommunityIcons name="home" color={color} size={26} />
),
}} />
<Tab.Screen name="Settings" component={Settings} options={{
tabBarLabel: 'Settings',
tabBarIcon: ({ color }) => (
<MaterialCommunityIcons name="home" color={color} size={26} />
),
}} />
</Tab.Navigator>
);
}
my code for a bottom tab navigator runs without any errors however when run in the emmulator the icons on the navigator do not display they are replaced by a crossed box? the tab navigator is also contained within a drawer content navigator which is in turn the child of a root stack navigator. all dependencies have been installed yet the error persists
Reading the documentation of the Tab.Navigator, you should define the icons inside of that. It would look like this:
<Tab.Navigator
screenOptions={({ route }) => ({
tabBarIcon: ({ focused, color, size }) => {
let iconName;
if (route.name === 'Home') {
iconName = focused
? 'ios-information-circle'
: 'ios-information-circle-outline';
} else if (route.name === 'Settings') {
iconName = focused ? 'ios-list-box' : 'ios-list';
}
// You can return any component that you like here!
return <MaterialCommunityIcons name={iconName} size={size} color={color} />;
},
})}
tabBarOptions={{
activeTintColor: 'tomato',
inactiveTintColor: 'gray',
}}
>
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="Settings" component={SettingsScreen} />
</Tab.Navigator>
This means you would be changing the component based on the route name. The reason behind it is that Tab.Screen should have information about the screen that will be displayed, while Tab.Navigator should handle the navigator (bottom strip with tabs) part of navigation.
Crossed box on android might come when the react-native-vector-icons is not link properly.
run this command
react-native link react-native-vector-icons
and in android/app/build.gradle file add this.
project.ext.vectoricons = [
iconFontNames: [ 'MaterialIcons.ttf' ] // Name of the font files you want to copy
]
apply from: "../../node_modules/react-native-vector-icons/fonts.gradle"
I hope this will fix your crossed box issue.
return statement is missing in your code.
You can do it like this:
<Tab.Screen name="Review Details" component={Review} options={{
tabBarLabel: 'Review',
tabBarIcon: ({ color }) => (
return <MaterialCommunityIcons name="home" color={color} size={26} />
),
}} />
So update this line,
<MaterialCommunityIcons name="home" color={color} size={26} />
to this
return <MaterialCommunityIcons name="home" color={color} size={26} />
I've created nested navigation using react-navigation version 5, But when tab screen render I need to hide top bar, I've follow step from here https://reactnavigation.org/docs/hiding-tabbar-in-screens/ but still not working
import * as React from 'react';
import {NavigationContainer} from '#react-navigation/native';
import {createStackNavigator} from '#react-navigation/stack';
import {createBottomTabNavigator} from '#react-navigation/bottom-tabs';
import {navigationRef} from './NavigationService';
import {Home, Appointment, Settings, Map, ProviderDetails} from 'app/screens';
import {PRIMARY_COLOR, SECONDARY_COLOR} from '../config/color';
import ThemeController from '../components/ThemeController';
import {StatusBar} from 'react-native';
import FontAwesome5 from 'react-native-vector-icons/FontAwesome5';
import MaterialIcons from 'react-native-vector-icons/MaterialIcons';
const Stack = createStackNavigator();
const homeOptions = {
title: 'Home',
headerTitleStyle: {
fontWeight: 'bold',
},
headerRight: () => <ThemeController />,
};
const HomeStack = () => {
return (
<Stack.Navigator>
<Stack.Screen name="Home" component={Home} />
</Stack.Navigator>
);
};
const MapStack = () => {
return (
<Stack.Navigator>
<Stack.Screen name="Map" component={Map} />
<Stack.Screen name="ProviderDetails" component={ProviderDetails} />
</Stack.Navigator>
);
};
const Tab = createBottomTabNavigator();
function App(props) {
const {theme} = props;
return (
<NavigationContainer ref={navigationRef} theme={theme}>
<StatusBar barStyle={theme.dark ? 'light-content' : 'dark-content'} />
<Tab.Navigator
screenOptions={({route}) => ({
tabBarIcon: ({focused, color, size}) => {
if (route.name === 'Home') {
return <MaterialIcons name="home" size={size} color={color} />;
} else if (route.name === 'Map') {
return (
<FontAwesome5 name="map-marked-alt" size={size} color={color} />
);
} else if (route.name === 'Appointment') {
return (
<FontAwesome5 name="calendar-alt" size={size} color={color} />
);
} else if (route.name === 'More') {
return (
<MaterialIcons name="more-horiz" size={size} color={color} />
);
}
},
})}
tabBarOptions={{
activeTintColor: PRIMARY_COLOR,
inactiveTintColor: SECONDARY_COLOR,
}}>
<Tab.Screen name="Home" component={HomeStack} />
<Tab.Screen name="Map" component={MapStack} />
<Tab.Screen name="Appointment" component={Appointment} />
<Tab.Screen name="More" component={Settings} />
</Tab.Navigator>
</NavigationContainer>
);
}
export default App;
Create HomeStack and MapStack stack navigator and pass that value to Tab Navigator,
In bellow image you can see in Home and Map tab display top bar.
Use headerShown option
const HomeStack = () => {
return (
<Stack.Navigator>
<Stack.Screen name="Home" options={{ headerShown: false }} component={Home} />
</Stack.Navigator>
);
};
https://reactnavigation.org/docs/material-bottom-tab-navigator
Using the above blog ,i have created bottom navigation bar.Error says on line 29 "component" predefined property of Tab.Screen should be capital.
Error in App
This is my BottomNavigation.js file
import * as React from 'react';
import {Text, View} from 'react-native';
import {NavigationContainer} from '#react-navigation/native';
import {createMaterialBottomTabNavigator} from '#react-navigation/material-bottom-tabs';
import NotificationsNoneIcon from '#material-ui/icons/NotificationsNone';
import AddCircleOutlineTwoToneIcon from '#material-ui/icons/AddCircleOutlineTwoTone';
import HomeOutlinedIcon from '#material-ui/icons/HomeOutlined';
import WbIncandescentOutlinedIcon from '#material-ui/icons/WbIncandescentOutlined';
import HomeScreen from '../screens/HomeScreen';
import AddDocument from '../screens/Notification';
import Notification from '../screens/AddDocument';
import AddProject from '../screens/AddProject';
const Tab = createMaterialBottomTabNavigator();
function MyTabs() {
return (
<Tab.Navigator
labeled="false"
activeColor="black"
labelStyle={{fontSize: 12}}
//style={{ backgroundColor: "black" }}
>
<Tab.Screen
name="Home"
component={HomeScreen}
options={{tabBarIcon: () => <HomeOutlinedIcon />}}
/>
<Tab.Screen
name="AddDocument"
component={AddDocument}
options={{tabBarIcon: () => <AddCircleOutlineTwoToneIcon />}}
/>
<Tab.Screen
name="AddProject"
component={AddProject}
options={{tabBarIcon: () => <WbIncandescentOutlinedIcon />}}
tabBarOptions={{showLabel: false}}
/>
<Tab.Screen
name="Notification"
component={Notification}
options={{tabBarIcon: () => <NotificationsNoneIcon />}}
/>
</Tab.Navigator>
);
}
export default class BottomNavigation extends React.Component {
render() {
return (
<NavigationContainer>
<MyTabs />
</NavigationContainer>
);
}
}
component is a property of Tab.screen but I am still getting error
Please help me
Thanks in advance
I was returning "NavigationContainer", Now I am simply returning Tab.Navigator to my App.js after that i am able to get bottom Navigator
My App.js looks like
export default function App() {
return (
<NavigationContainer>
<BottomNavigation />
</NavigationContainer>
);
}
i just removed NavigationContainer from BottomNavigation.But now my icon isn't getting displayed.
Modified BottomNavigation.js File
import * as React from 'react';
import {createMaterialBottomTabNavigator} from '#react-navigation/material-bottom-tabs';
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
import AntDesign from 'react-native-vector-icons/AntDesign';
import SimpleLineIcons from 'react-native-vector-icons/SimpleLineIcons';
import HomeScreen from '../screens/HomeScreen';
import AddDocument from '../screens/Notification';
import Notification from '../screens/AddDocument';
import AddProject from '../screens/AddProject';
const Tab = createMaterialBottomTabNavigator();
export default function BottomNavigation(props) {
return (
<Tab.Navigator
// labeled="false"
labelStyle={{fontSize: 12}}
inactiveColor="white"
activeColor="white"
//style={{backgroundColor: 'black'}}
>
<Tab.Screen
name="Home"
component={HomeScreen}
options={{
tabBarIcon: ({color}) => (
<MaterialCommunityIcons
name="home-outline"
color={color}
size={26}
/>
),
}}
/>
<Tab.Screen
name="AddDocument"
component={AddDocument}
options={{
tabBarIcon: ({color}) => (
<AntDesign name="addfile" color={color} size={26} />
),
}}
/>
<Tab.Screen
name="AddProject"
component={AddProject}
options={{
tabBarIcon: ({color}) => (
<SimpleLineIcons name="magnifier-add" color={color} size={26} />
),
}}
tabBarOptions={{showLabel: false}}
/>
<Tab.Screen
name="Notification"
component={Notification}
options={{
tabBarIcon: ({color}) => (
<MaterialCommunityIcons
name="bell-outline"
color={color}
size={26}
/>
),
}}
/>
</Tab.Navigator>
);
}
My icons were not getting displayed so I referred to https://github.com/oblador/react-native-vector-icons/issues/463 just executed
react-native link
and now my bottom Navigation Bar is working perfectly.