Bottom navigation is not working on react-native - react-native

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.

Related

How to isolate a React Navigation Tab in standalone comopnent?

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>
);

React Navigation - why navigation bar is appearing below header but not at the bottom

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 />
);
}

React Native Top Area View

I'm new to React Native and I have a very simple first page that I'm testing out. My only thing I'm having a hard time understanding is where there is a Title view at the top area. Here's what my app currently looks like https://i.stack.imgur.com/H7vbO.png As you can see, there's that huge white space that has "Home" in it. I'm trying to get rid of it completely and just have the my background color throughout the whole thing. My only problem is that I don't even know where that is coming from. Here is my code and thank you.
This is my HomeScreen
import React from "react";
import { StyleSheet, Text, SafeAreaView, Platform } from "react-native";
import { StatusBar } from "expo-status-bar";
const HomeScreen = ({}) => {
return (
<SafeAreaView style={styles.container}>
<Text style={{ color: "white" }}>Home Screen</Text>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#4B4B4B",
alignItems: "center",
paddingTop: Platform.OS === "android" ? StatusBar.currentHeight : 0,
},
});
export default HomeScreen;
This is my App.js
import React from "react";
import { NavigationContainer } from "#react-navigation/native";
import { createNativeStackNavigator } from "#react-navigation/native-stack";
import MainTabScreen from "./screens/MainTabScreen";
const Stack = createNativeStackNavigator();
const App = () => {
return (
<NavigationContainer>
<MainTabScreen />
</NavigationContainer>
);
};
export default App;
Here is my MainTabScreen
import React from "react";
import { createBottomTabNavigator } from "#react-navigation/bottom-tabs";
import Icon from "react-native-vector-icons/Ionicons";
import HomeScreen from "./HomeScreen";
import SearchScreen from "./SearchScreen";
import InboxScreen from "./InboxScreen";
import AccoutScreen from "./AccountScreen";
const Tab = createBottomTabNavigator();
const MainTabScreen = () => {
return (
<Tab.Navigator initialRouteName="Home" activeColor="#000000">
<Tab.Screen
name="Home"
component={HomeScreen}
options={{
tabBarIcon: ({ color }) => (
<Icon name="ios-home" color={color} size={26} />
),
}}
/>
<Tab.Screen
name="Search"
component={SearchScreen}
options={{
tabBarIcon: ({ color }) => (
<Icon name="ios-search" color={color} size={26} />
),
}}
/>
<Tab.Screen
name="Inbox"
component={InboxScreen}
options={{
tabBarIcon: ({ color }) => (
<Icon name="ios-chatbox" color={color} size={26} />
),
}}
/>
<Tab.Screen
name="Account"
component={AccoutScreen}
options={{
tabBarIcon: ({ color }) => (
<Icon name="ios-person" color={color} size={26} />
),
}}
/>
</Tab.Navigator>
);
};
export default MainTabScreen;
P.S.: I already tried changing SafeAreaView to just View, and I also try removing the padding top
That view is actually the header of the navigator. Thus, to remove it, on your main navigator, set headerShown: false.
In your mainTabScreen;
<Tab.Navigator screenOptions={{headerShown: false}} initialRouteName="Home" activeColor="#000000">
...
Rest will be same.
Bottom tab accepts header related options in options property of Navigator Screens and screenOptions property in The Navigator Component
e.g
const MainTabScreen = () => {
return (
<Tab.Navigator
initialRouteName="Home"
activeColor="#000000"
// To remove header from all screens,
// screenOptions={{ headerShown: false }}
>
<Tab.Screen
name="Home"
component={Home}
options={{
tabBarIcon: ({ color }) => (
<Icon name="ios-home" color={color} size={26} />
),
// Update Header Title
// headerTitle: 'NOT A HOME',
}}
/>
<Tab.Screen
name="Search"
component={Home}
options={{
tabBarIcon: ({ color }) => (
<Icon name="ios-search" color={color} size={26} />
),
}}
/>
</Tab.Navigator>
);
};
You can read about all header related options in - https://reactnavigation.org/docs/elements#header

how can i mock createBottomTabNavigator from #react-navigation/bottom-tabs in Jest

I can't seem to be able to test my bottom navigator with Jest.
here's my navigator :
import * as React from 'react';
import 'react-native-gesture-handler';
import Icon from 'react-native-vector-icons/FontAwesome';
import IonIcon from 'react-native-vector-icons/Octicons';
import {NavigationContainer} from '#react-navigation/native';
import {createBottomTabNavigator} from '#react-navigation/bottom-tabs';
import HomeNavigator from './routes/home';
import SearchNavigator from './routes/search';
export default function Navigator() {
const Tab = createBottomTabNavigator();
return (
<NavigationContainer>
<Tab.Navigator
tabBarOptions={{
keyboardHidesTabBar: true,
}}>
<Tab.Screen
name="Home"
component={HomeNavigator}
options={{
tabBarLabel: 'Home',
tabBarIcon: ({color, size}) => (
<Icon name="home" color={color} size={size} />
),
}}
/>
<Tab.Screen
name="Search"
component={SearchNavigator}
options={{
tabBarLabel: 'Search',
tabBarIcon: ({color, size}) => (
<IonIcon
name="search"
color={color}
size={size}
style={{transform: [{scaleX: -1}]}}
/>
),
}}
/>
</Tab.Navigator>
</NavigationContainer>
);
}
navigation/index.js
my redux wrapper component's render function:
<Provider store={global.store}>
<PersistGate loading={null} persistor={global.persistor}>
{this.props.children}
</PersistGate>
</Provider>
redux_wrapper.js
My navigator.test.js
import * as React from 'react';
import {NavigationContainer} from '#react-navigation/native';
import {render, fireEvent} from '#testing-library/react-native';
import ReduxWrapper from '../src/redux/redux_wrapper';
import HomeNavigator from '../src/navigation/routes/home';
jest.mock('react-native/Libraries/Animated/NativeAnimatedHelper');
describe('Testing react navigation', () => {
test('page contains the header and 10 items', async () => {
const component = (
<ReduxWrapper>
<NavigationContainer>
<HomeNavigator />
</NavigationContainer>
</ReduxWrapper>
);
const {getAllByTestId} = render(component);
const homeScene = getAllByTestId('homeScene');
expect(homeScene).toBeTruthy();
});
});
navigator.test.js
when i try to run it , i get the following error from Jest:
how can i test this correctly , knowing that my main intention here is to test the navigation to a details screen later on ?
The getByTestID function looks at the testID= attributes of the rendered components.
You've not shared the code for HomeNavigator but if you change it to something like:
// './routes/home'
<View testID="homeScene">
{ /* rest of the HomeNavigator code */ }
</View>
You might also need to set the initialRouteName attribute in your <Tab.Navigator JSX.
<Tab.Navigator
initialRouteName="Home"
tabBarOptions={{
keyboardHidesTabBar: true,
}}>
<Tab.Screen
...
</Tab.Navigator>

How can I hide the bottom tab bar on a specific screen (react navigation 5.x)

I wanted to know how to hide the bottom tab bar from a specific screen inside my stack navigator, my code is below. I just want to hide bottom tabs for the Player screen, or open Player screen with modal can anyone help me?
This is my code for my main tab navigator
import React from 'react';
import { StatusBar } from 'react-native';
import { NavigationContainer, DarkTheme } from '#react-navigation/native';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
//views
import HomeStack from './src/views/Home';
import SearchStack from './src/views/Search';
import MoviesStack from './src/views/Movies';
import SeriesStack from './src/views/Series';
import Other from './src/views/Other';
//icons
import {
HomeIcon,
SearchIcon,
MovieIcon,
SeriesIcon,
OtherIcon,
} from './src/components/icons';
const Tab = createBottomTabNavigator();
export default function App() {
return (
<>
<StatusBar barStyle="dark-content" />
<NavigationContainer theme={DarkTheme}>
<Tab.Navigator
initialRouteName="Home"
tabBarOptions={{
activeTintColor: 'white',
keyboardHidesTabBar: false,
}}
>
<Tab.Screen
name="Home"
component={HomeStack}
options={{
tabBarLabel: 'Home',
tabBarIcon: ({ focused }) => (
<HomeIcon
fill={focused ? 'white' : 'gray'}
width={24}
height={24}
/>
),
}}
/>
<Tab.Screen
name="Search"
component={SearchStack}
options={{
tabBarLabel: 'Search',
tabBarIcon: ({ focused }) => (
<SearchIcon
stroke={focused ? 'white' : 'gray'}
width={24}
height={24}
/>
),
}}
/>
<Tab.Screen
name="Movie"
component={MoviesStack}
options={{
tabBarLabel: 'Movie',
tabBarIcon: ({ focused }) => (
<MovieIcon
color={focused ? 'white' : 'gray'}
width={24}
height={24}
/>
),
}}
/>
<Tab.Screen
name="Series"
component={SeriesStack}
options={{
tabBarLabel: 'Series',
tabBarIcon: ({ focused }) => (
<SeriesIcon
color={focused ? 'white' : 'gray'}
width={24}
height={24}
/>
),
}}
/>
<Tab.Screen
name="Other"
component={Other}
options={{
tabBarLabel: 'Other',
tabBarIcon: ({ focused }) => (
<OtherIcon
fill={focused ? 'white' : 'gray'}
width={24}
height={24}
/>
),
}}
/>
</Tab.Navigator>
</NavigationContainer>
</>
);
}
This is my code for my main stack navigator
import React from 'react';
import { View, Image } from 'react-native';
import { createStackNavigator } from '#react-navigation/stack';
//components
import Screen from '../components/Screen';
import HomeList from '../components/HomeList';
//views
import MovieDetail from './MovieDetail';
import SeriesDetail from './SeriesDetail';
import Player from './Player';
function Home({ navigation }) {
return (
<Screen>
<View>
<Image source={require('../../assets/logo.png')} />
...
</View>
</Screen>
);
}
const Stack = createStackNavigator();
export default function HomeStack() {
return (
<Stack.Navigator
screenOptions={{
headerShown: false,
}}
>
<Stack.Screen name="Home" component={Home} />
<Stack.Screen name="MovieDetail" component={MovieDetail} />
<Stack.Screen name="SeriesDetail" component={SeriesDetail} />
<Stack.Screen name="Player" component={Player} />
</Stack.Navigator>
);
}
and this is my code for stack navigator of the page I use to send data to the page i want to hide
import React from 'react';
import {
View,
Text,
TouchableOpacity,
} from 'react-native';
//components
import Screen from '../components/Screen';
import Loading from '../components/Loading';
export default function MovieDetail({ route, navigation }) {
const { id, title } = route.params;
return (
<Screen>
<TouchableOpacity
activeOpacity={0.7}
onPress={() =>
navigation.navigate('Player', {
uri: 'https://blabla.com',
})
}
>
<PlayIcon color="black" />
<Text>
Play
</Text>
</TouchableOpacity>
</Screen>
);
}
and here I want to hide tab bar this screen
import React from 'react';
import WebView from 'react-native-webview';
export default function Player({ route }) {
const { uri } = route.params;
return (
<WebView source={{ uri }} />
);
}
Ciao, you can hide bottom tabbar in Player screen like that:
Modify your Tab.Screen Home like this:
<Tab.Screen
name="Home"
component={HomeStack}
options={({ route }) => ({
tabBarLabel: 'Keşfet',
tabBarIcon: ({ focused }) => (
<HomeIcon
fill={focused ? 'white' : 'gray'}
width={24}
height={24}
/>
),
tabBarVisible: getTabBarVisibility(route),
})}
/>
Then create getTabBarVisibility function to check that the name of the root is Player:
const getTabBarVisibility = (route) => {
const routeName = route.state
? route.state.routes[route.state.index].name
: '';
if (routeName === 'Player') {
return false;
}
return true;
};
That's it. Now if you navigate into Player page, tabBar disappears.