BottomTabNavigator not working in React Native - react-native

I am using Drawer,Stack and Tab navigator using React Navigation 5, I have followed documentation but Tab Navigator not showing.
Here's my code:
In my app.js I have called my main StackNavigator:
const Stack = createStackNavigator();
export default class App extends React.Component {
render() {
return (
<NavigationContainer>
<Stack.Navigator headerMode="none" initialRouteName="HomePage">
<Stack.Screen name="Home" component={HomePage} />
<Stack.Screen name="Login" component={LoginSignUp} />
<Stack.Screen name="DrawerScreenss" component={DrawerScreens} />
<Stack.Screen name="Tab" component={TabComp} />
</Stack.Navigator>
</NavigationContainer>
);
}
}
This is my Drawer Navigation Code:
import * as React from 'react';
import { createDrawerNavigator } from '#react-navigation/drawer';
import DrawerContent from './DrawerComponents/DrawerContent';
import DrawerHome from './DrawerComponents/DrawerHome';
const Drawer = createDrawerNavigator();
export default class DrawerScreens extends React.Component {
render() {
return (
<Drawer.Navigator
drawerContent={() => (
<DrawerContent navigation={this.props.navigation} />
)}>
<Drawer.Screen name="DrawHome" component={DrawerHome} />
</Drawer.Navigator>
);
}
}
Here's my TabNavigator which is not working:
import React, { Component } from "react";
import { createBottomTabNavigator } from "#react-navigation/bottom-tabs";
import DrawerHome from "./DrawerHome";
import Bookmarks from "./Bookmarks";
export default class TabComp extends Component {
render() {
const Tab = createBottomTabNavigator();
return (
<Tab.Navigator
initialRouteName="Home"
tabBarOptions={{
activeTintColor: "#e91e63",
activeTintColor: "red",
inactiveTintColor: "grey",
style: {
backgroundColor: "white",
borderTopColor: "red"
},
labelStyle: {
fontSize: 12,
fontWeight: "normal"
},
indicatorStyle: {
borderBottomColor: "red",
borderBottomWidth: 4
}
}}
>
<Tab.Screen name="Home" component={DrawerHome} />
<Tab.Screen name="Bookmarks" component={Bookmarks} />
</Tab.Navigator>
);
}
}
It should be visible in my DrawerHome screens but not working

I don't know exactly what your HomePage component looks like, but it could look something like this with a button that navigates to your DrawerScreens screen:
const HomePage = ({navigation}) => {
return (
<View style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
<Text>Feed Screen</Text>
<Button
title="Go to DrawerScreens"
onPress={() => navigation.navigate('DrawerScreens')}
/>
</View>
);
};
The important thing I changed in your DrawerScreens component is that its screen is your TabComp component:
class DrawerScreens extends React.Component {
render() {
return (
<Drawer.Navigator
drawerContent={() => (
<DrawerContent navigation={this.props.navigation} />
)}>
<Drawer.Screen name="Tab" component={TabComp} />
</Drawer.Navigator>
);
}
}
The TabComp component itself can stay the same.
Then inside your DrawerHome component you can trigger your drawer using navigation.openDrawer().
const DrawerHome = ({navigation}) => {
return (
<View style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
<Text>Feed Screen</Text>
<Button title="Open Drawer" onPress={() => navigation.openDrawer()} />
</View>
);
};
This way you can show your tabs and your drawer at the same time.

Related

React native (React navigation)- instance of same screen in differents tabs. Navigate from drawer

I have an issue with react navigation.
I would like to have the same behavior as the linkedIn app has.
I mean, in that app, you can open the settings page from the drawer in differents tabs. You can open it from the first tab, second one... and so on. and at the end you get multiple instances.
I am not able to reproduce this behavior
My navigation is:
One drawer with one drawer screen (one Tab navigator inside). 3 tabs screens inside that Tab navigator. Each one contains a stack. I have set the same screens in that screen. For example I want to share the Profile, so I have one profile screen in each tab.
In the customDrawer I navigate to screens name, but here is the problem. React navigation does not know what stack should call before calling the right screen.
And I cannot find a way to know the current mounted stack so I cannot set it dinamically in order to do inside the custom drawer:
onPress={() =>
props.navigation.navigate(Routes.student.home.STACK, { screen: Routes.student.SETTINGS })
}
Thanks!
App.tsx
/* eslint-disable react-native/no-inline-styles */
import 'react-native-gesture-handler';
import React from 'react';
import { Text } from 'react-native';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
import {
createDrawerNavigator,
DrawerContentScrollView,
DrawerItem,
} from '#react-navigation/drawer';
import { NavigationContainer } from '#react-navigation/native';
import { QueryClient, QueryClientProvider } from '#tanstack/react-query';
import { StatusBar } from 'expo-status-bar';
import HomeStackScreen from '#pages/Home';
import { Routes } from '#src/constants/routes';
import { PracticalStackScreen } from '#src/pages/Practical/Practical';
import { TheoryStackScreen } from '#src/pages/Theory/Theory';
// Create a client
const queryClient = new QueryClient();
const Tab = createBottomTabNavigator();
const Drawer = createDrawerNavigator();
const TabNavigator = () => {
return (
<Tab.Navigator
screenOptions={{ headerShown: false }}
initialRouteName={Routes.student.home.STACK}
>
<Tab.Screen
name={Routes.student.theory.STACK}
component={TheoryStackScreen}
options={{ title: 'TEÓRICO' }}
/>
<Tab.Screen
name={Routes.student.home.STACK}
component={HomeStackScreen}
options={{ title: '' }}
/>
<Tab.Screen
name={Routes.student.practical.STACK}
component={PracticalStackScreen}
options={{ title: 'PRÁCTICO' }}
/>
</Tab.Navigator>
);
};
function CustomDrawerContent(props: any) {
console.log('props ', props);
return (
<DrawerContentScrollView {...props}>
<Text>Mi cuenta</Text>
<DrawerItem
label='Configuración'
onPress={() => props.navigation.navigate(Routes.student.SETTINGS)}
/>
<DrawerItem
label='Métodos de pago'
onPress={() => props.navigation.navigate(Routes.student.PAYMENT)}
/>
<Text>Social</Text>
<DrawerItem
label='Tiktok'
onPress={() => props.navigation.navigate(Routes.student.PROFILE)}
/>
<Text>Ayuda</Text>
<DrawerItem
label='Preguntas frecuentes'
onPress={() => props.navigation.navigate(Routes.student.FAQ)}
/>
<DrawerItem
label='Atención al alumno'
onPress={() => props.navigation.navigate(Routes.student.STUDENT_SUPPORT)}
/>
</DrawerContentScrollView>
);
}
const DrawerNavigation = () => {
return (
<Drawer.Navigator
useLegacyImplementation={true}
drawerContent={(props) => <CustomDrawerContent {...props} />}
initialRouteName={Routes.student.home.STACK}
>
<Drawer.Screen name={Routes.MAIN_TAB} component={TabNavigator} />
</Drawer.Navigator>
);
};
export default function App() {
return (
<QueryClientProvider client={queryClient}>
<StatusBar />
<NavigationContainer>
<DrawerNavigation />
</NavigationContainer>
</QueryClientProvider>
);
}
Home.tsx
/* eslint-disable react-native/no-color-literals */
import React from 'react';
import { StyleSheet, Text, View, Pressable } from 'react-native';
import { createNativeStackNavigator } from '#react-navigation/native-stack';
import { Routes } from '#src/constants/routes';
import Faq from '../Faq';
import Payment from '../Payment';
import Profile from '../Profile';
import Settings from '../Settings';
import StudentSupport from '../StudentSupport';
const HomeStack = createNativeStackNavigator();
export const HomeStackScreen = (): JSX.Element => {
return (
<HomeStack.Navigator
screenOptions={{ headerStyle: { backgroundColor: 'red' }, headerShown: false }}
>
<HomeStack.Screen name={Routes.student.home.MAIN} component={Home} />
<HomeStack.Screen name={Routes.student.PROFILE} component={Profile} />
<HomeStack.Screen name={Routes.student.SETTINGS} component={Settings} />
<HomeStack.Screen name={Routes.student.PAYMENT} component={Payment} />
<HomeStack.Screen name={Routes.student.FAQ} component={Faq} />
<HomeStack.Screen name={Routes.student.STUDENT_SUPPORT} component={StudentSupport} />
</HomeStack.Navigator>
);
};
export const Home = ({ navigation }: any): JSX.Element => (
<View style={styles.container}>
<Text>Home Screen</Text>
<Pressable style={styles.button} onPress={() => navigation.navigate(Routes.student.PROFILE)}>
<Text style={styles.text}>Perfil</Text>
</Pressable>
</View>
);
const backgroundColor = '#fff';
const styles = StyleSheet.create({
button: {
alignItems: 'center',
backgroundColor: 'grey',
borderRadius: 4,
elevation: 3,
justifyContent: 'center',
paddingHorizontal: 32,
paddingVertical: 12,
},
container: {
alignItems: 'center',
backgroundColor,
flex: 1,
justifyContent: 'center',
},
text: {
color: 'white',
fontSize: 16,
fontWeight: 'bold',
letterSpacing: 0.25,
lineHeight: 21,
},
});
Theroy.tsx
import React from 'react';
import { Button, StyleSheet, Text, View } from 'react-native';
import { createNativeStackNavigator } from '#react-navigation/native-stack';
import { Routes } from '#src/constants/routes';
import Faq from '../Faq';
import Payment from '../Payment';
import Profile from '../Profile';
import Settings from '../Settings';
import StudentSupport from '../StudentSupport';
const TheoryStack = createNativeStackNavigator();
export const TheoryStackScreen = (): JSX.Element => {
return (
<TheoryStack.Navigator
screenOptions={{ headerStyle: { backgroundColor: 'red' }, headerShown: false }}
>
<TheoryStack.Screen name={Routes.student.theory.MAIN} component={Theory} />
<TheoryStack.Screen name={Routes.student.PROFILE} component={Profile} />
<TheoryStack.Screen name={Routes.student.SETTINGS} component={Settings} />
<TheoryStack.Screen name={Routes.student.PAYMENT} component={Payment} />
<TheoryStack.Screen name={Routes.student.FAQ} component={Faq} />
<TheoryStack.Screen name={Routes.student.STUDENT_SUPPORT} component={StudentSupport} />
</TheoryStack.Navigator>
);
};
export function Theory({ navigation }: any): JSX.Element {
return (
<View style={styles.container}>
<Text>Theory Screen</Text>
<Button title='Go to Home' onPress={() => navigation.navigate(Routes.student.home.STACK)} />
<Button
title='Go to Practical'
onPress={() => navigation.navigate(Routes.student.practical.STACK)}
/>
<Button
title='Go to Profile'
onPress={() =>
navigation.navigate(Routes.student.home.STACK, { screen: Routes.student.PROFILE })
}
/>
</View>
);
}
const backgroundColor = '#fff';
const styles = StyleSheet.create({
container: {
alignItems: 'center',
backgroundColor,
flex: 1,
justifyContent: 'center',
},
});
Practical.tsx
import React from 'react';
import { Button, StyleSheet, Text, View } from 'react-native';
import { createNativeStackNavigator } from '#react-navigation/native-stack';
import { Routes } from '#src/constants/routes';
import Faq from '../Faq';
import Payment from '../Payment';
import Profile from '../Profile';
import Settings from '../Settings';
import StudentSupport from '../StudentSupport';
const PracticalStack = createNativeStackNavigator();
export const PracticalStackScreen = (): JSX.Element => {
return (
<PracticalStack.Navigator
screenOptions={{ headerStyle: { backgroundColor: 'red' }, headerShown: false }}
>
<PracticalStack.Screen name={Routes.student.practical.MAIN} component={Practical} />
<PracticalStack.Screen name={Routes.student.PROFILE} component={Profile} />
<PracticalStack.Screen name={Routes.student.SETTINGS} component={Settings} />
<PracticalStack.Screen name={Routes.student.PAYMENT} component={Payment} />
<PracticalStack.Screen name={Routes.student.FAQ} component={Faq} />
<PracticalStack.Screen name={Routes.student.STUDENT_SUPPORT} component={StudentSupport} />
</PracticalStack.Navigator>
);
};
export function Practical({ navigation }: any): JSX.Element {
return (
<View style={styles.container}>
<Text>Practical Screen</Text>
<Button title='Go to Home' onPress={() => navigation.navigate(Routes.student.home.STACK)} />
<Button
title='Go to Theory'
onPress={() => navigation.navigate(Routes.student.theory.STACK)}
/>
<Button
title='Go to Profile'
onPress={() =>
navigation.navigate(Routes.student.home.STACK, { screen: Routes.student.PROFILE })
}
/>
</View>
);
}
const backgroundColor = '#fff';
const styles = StyleSheet.create({
container: {
alignItems: 'center',
backgroundColor,
flex: 1,
justifyContent: 'center',
},
});
Try renaming your Settings screen component differently for each stack navigator. So something like
<PracticalStack.Screen name="Practical/Settings" component={Settings} />
<HomeStack.Screen name="Home/Settings" component={Settings} />
Then you could navigate to the appropriate screen from your drawer based on the tab in focus.
I think I found a possible solution to my question. I have changed the CustomDrawerContent.
function CustomDrawerContent(props: any) {
const drawerState = props.state.routes[0]?.state;
const routeIndex = drawerState?.index;
const focusedTab = drawerState?.routes?.[routeIndex]?.name || Routes.student.home.STACK;
return (
<DrawerContentScrollView {...props}>
<Text>Mi cuenta</Text>
<DrawerItem
label='Configuración'
onPress={() => props.navigation.navigate(focusedTab, { screen: Routes.student.SETTINGS })}
/>
<DrawerItem
label='Métodos de pago'
onPress={() => props.navigation.navigate(focusedTab, { screen: Routes.student.PAYMENT })}
/>
<Text>Social</Text>
<DrawerItem
label='Tiktok'
onPress={() => props.navigation.navigate(focusedTab, { screen: Routes.student.PROFILE })}
/>
<Text>Ayuda</Text>
<DrawerItem
label='Preguntas frecuentes'
onPress={() => props.navigation.navigate(focusedTab, { screen: Routes.student.FAQ })}
/>
<DrawerItem
label='Atención al alumno'
onPress={() =>
props.navigation.navigate(focusedTab, { screen: Routes.student.STUDENT_SUPPORT })
}
/>
</DrawerContentScrollView>
);
}

toggleDrawer from #react-navigation/drawer not working in React-Native

I made a nested navigation Drawer + Stack, but the drawer is not working, I am not able to toggle the drawer, but able to drag the drawer from the left side and it goes back closing automatically after releasing it.
Also, I get a pop up when hovering over navigation.toggleDrawer(), this is what I get
Property 'toggleDrawer' does not exist on type
'NavigationProp<ParamListBase, string, Readonly<{ key: string; index:
number; routeNames: string[]; history?: unknown[]; routes:
NavigationRoute<ParamListBase, string>[]; type: string; stale: false;
}>, {}, {}>'
So what's wrong here and how to fix it? And can I make a drawer without using #react-navigation/drawer ?
app.js :
import React from "react";
import { NavigationContainer } from "#react-navigation/native";
import { createStackNavigator } from "#react-navigation/stack";
import HomeScreen from "./src/screens/HomeScreen";
import MovieScreen from "./src/screens/MovieScreen";
import FavoriteScreen from "./src/screens/FavoritesScreen";
import { useFonts } from "expo-font";
import AppLoading from "expo-app-loading";
import { createDrawerNavigator } from "#react-navigation/drawer";
import CustomDrawerContent from "./src/components/DrawerContent";
const Stack = createStackNavigator();
const Drawer = createDrawerNavigator();
function HomeStackScreen() {
return (
<Stack.Navigator>
<Stack.Screen
name='home'
component={HomeScreen}
options={{ headerShown: false }}
/>
<Stack.Screen
name='movie'
component={MovieScreen}
options={{ headerShown: false }}
/>
</Stack.Navigator>
);
}
export default () => {
const [fontLoaded] = useFonts({
Regular: require("./assets/fonts/NunitoSans-Regular.ttf"),
Bold: require("./assets/fonts/NunitoSans-Bold.ttf"),
Black: require("./assets/fonts/NunitoSans-Black.ttf"),
ExtraBold: require("./assets/fonts/NunitoSans-ExtraBold.ttf"),
ExtraLight: require("./assets/fonts/NunitoSans-ExtraLight.ttf"),
Light: require("./assets/fonts/NunitoSans-Light.ttf"),
SemiBold: require("./assets/fonts/NunitoSans-SemiBold.ttf"),
});
return fontLoaded ? (
<NavigationContainer>
<Drawer.Navigator
drawerContent={(props) => <CustomDrawerContent {...props} />}
initialRouteName='Home'
screenOptions={{ drawerPosition: "left", drawerType: "front" }}
>
<Drawer.Screen
name='home'
component={HomeStackScreen}
options={{ headerShown: false }}
/>
<Drawer.Screen
name='fav'
component={FavoriteScreen}
options={{ headerShown: false }}
/>
</Drawer.Navigator>
</NavigationContainer>
) : (
<AppLoading />
);
};
home.js
import { useNavigation } from "#react-navigation/native";
export default function HomeScreen(){
const navigation = useNavigation();
return(
<ScrollView style={styles.container}>
<StatusBar
style='auto'
translucent={false}
backgroundColor={COLORS.BASIC_BACKGROUND}
/>
<View
style={{
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center",
paddingHorizontal: 20,
paddingVertical: 10,
}}
>
<Pressable
style={{ flex: 1 }}
onPress={() => {
navigation.toggleDrawer();
console.log("Clicked on Menu Bar");
}}
>
<Image
style={{ width: 25, height: 28 }}
source={{
uri: "https://img.icons8.com/material-rounded/96/000000/menu--v1.png",
}}
/>
</Pressable>
</View>
</ScrollView>
)
}

How to define routes in React Native without displaying them in a navigator?

I have a bottom tab navigator made with React Navigation on a basic React Native app. It only gives access to 4 screens. Some screens may contains buttons that would open a new page (for example: a user profile page). How to define the route without displaying it in the bottom tab navigator?
The code:
const Tab = createBottomTabNavigator();
export default function Router() {
const { t } = useTranslation();
return (
<Tab.Navigator initialRouteName={screen.home}>
<Tab.Screen name={screen.home} component={Home}/>
<Tab.Screen name={screen.a} component={A}/>
<Tab.Screen name={screen.b} component={B}/>
<Tab.Screen name={screen.c} component={C}/>
</Tab.Navigator>
);
}
The idea would be to allow a click like that:
function ScreenB(){
const navigation = useNavigation();
return (
<TouchableOpacity onPress={() => navigation.navigate("/user/123")}>
<Text>see user 123</Text>
</TouchableOpacity>
)
}
Thanks for your help!
Online example https://snack.expo.io/#vasylnahuliak/great-bubblegum
import * as React from 'react';
import { Button, Text, View } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
const HomeScreen = ({ navigation }) => {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Home screen</Text>
</View>
);
};
const ProfileScreen = ({ navigation }) => {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Settings screen</Text>
<Button
title="Go to Details"
onPress={() => navigation.navigate('Details')}
/>
</View>
);
};
const DetailsScreen = () => { // <--- Screen without navigation header
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Details screen</Text>
</View>
);
};
const ProfileStack = createStackNavigator();
const ProfileStackScreen = () => {
return (
<ProfileStack.Navigator>
<ProfileStack.Screen name="Settings" component={ProfileScreen} />
</ProfileStack.Navigator>
);
};
const MainTab = createBottomTabNavigator();
const MainTabs = () => {
return (
<MainTab.Navigator>
<MainTab.Screen name="Home" component={HomeScreen} />
<MainTab.Screen name="Profile" component={ProfileStackScreen} />
</MainTab.Navigator>
);
};
const RootStack = createStackNavigator();
export default function App() {
return (
<NavigationContainer>
<RootStack.Navigator>
<RootStack.Screen
name="MainTabs"
component={MainTabs}
options={{ headerShown: false }}
/>
<RootStack.Screen name="Details" component={DetailsScreen} /> // <--- Screen without navigation header
</RootStack.Navigator>
</NavigationContainer>
);
}
Official documentation: https://reactnavigation.org/docs/hiding-tabbar-in-screens

react-navigation v5 - how to toggle drawer

I upgraded to react-navigation V5, and am so confused how to get the Drawer to work. I had a custom drawer before, but now I'm just trying to get a sample drawer working.
I am trying to open the drawer with this.props.navigation.dispatch(DrawerActions.toggleDrawer())
The action 'TOGGLE_DRAWER' was not handled by any navigator.
Is your screen inside a Drawer navigator?
Here are the relevant files:
MessagesStackRouter.js
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import { createDrawerNavigator } from '#react-navigation/drawer';
const Stack = createStackNavigator();
const Drawer = createDrawerNavigator();
function DrawerNavigation() {
return (
<Drawer.Navigator
drawerType={"slide"}
>
<Drawer.Screen name="Dash" component={DashboardContainer} />
</Drawer.Navigator>
);
}
function MessagesStackRouter() {
return (
<NavigationContainer>
<Stack.Navigator
initalRoute="Login"
screenOptions={{ gestureEnabled: true, headerShown: false }}
>
<Stack.Screen name="Login" component={LoginView} />
<Stack.Screen name="DrawerNavigation" component={DrawerNavigation} />
<Stack.Screen name="Dashboard" component={DashboardContainer} />
</Stack.Navigator>
</NavigationContainer>
);
}
export default MessagesStackRouter;
App.js
return (
<View style={{flex:1, backgroundColor: 'white'}}>
<StatusBar hidden={true} />
<Provider store={createStore(reducers)}>
<MessagesScreenRouter/>
</Provider>
</View>
);
relevant parts of TopNavBar.js
import { DrawerActions } from '#react-navigation/native';
class TopNavBar extends Component {
constructor(props) {
super(props);
this.onBurgerBarPress = this.onBurgerBarPress.bind(this)
}
onBurgerBarPress() {
this.props.navigation.dispatch(DrawerActions.toggleDrawer())
}
render() {
return (
<View style={styles.navBar}>
<View style={{ flex: 1, flexDirection: 'row', justifyContent: 'space-between', marginTop: 10 }}>
<TouchableOpacity onPress={()=> this.onBurgerBarPress()}>
<Icon
name={"Menu"}
strokeWidth="1.5"
stroke={'#03A9F4' }
fill={'#03A9F4'}
/>
</TouchableOpacity>
</View>
</View>
)
}
};
const mapStateToProps = (state) => {
return {
onboarding: state.onboarding,
currentUser: state.currentUser
}
}
export default connect(mapStateToProps, actions)(TopNavBar);
You get an error because the screen where you have the drawer navigator is not rendered. You should nest the stack navigator inside the drawer navigator instead of drawer inside stack which will work better for your case.

× TypeError: Cannot read property 'navigate' of undefined on React-Native expo react-navigation 5.xx

If somebody can help me.
I'm sure that I miss something, but I can't see it.I'm trying to do navigation between 3 components and I create it with the documentation from the react-navigation page, I try a lot of different ways to do it, but always receive the same answer, so if somebody can see the mistake I do please tell me.
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import Header from './app/components/header/header'
import Main from './app/components/main/main';
import Data from './app/components/data/data';
import Grafic from './app/components/grafic/grafic';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import ButtonImage from './app/components/buttonImag/buttonImg'
import 'react-native-gesture-handler';
const Stack = createStackNavigator();
function MainScreen({ navigation }) {
return (
<ButtonImage onPress={() => navigation.navigate('Main')} heightV={40} widthV={40} itemImage={require('./app/resourse/home.png')} heightI={33} widthI={33} ></ButtonImage>
);
};
function DataScreen({ navigation }) {
return (
<ButtonImage onPress={() => navigation.navigate('Data')} heightV={40} widthV={40} itemImage={require('./app/resourse/datalist.png')} heightI={33} widthI={33} ></ButtonImage>
);
};
function GraficScreen({ navigation }) {
return (
<ButtonImage onPress={() => navigation.navigate('Grafic')} heightV={40} widthV={40} itemImage={require('./app/resourse/grafic.png')} heightI={33} widthI={33} ></ButtonImage>
);
};
const Footer = ({ navigation }) => {
return (
<View style={styles.header}>
<View style={styles.buttonPos}>
<MainScreen />
<DataScreen />
<GraficScreen />
</View>
</View>
)
};
function MyStack() {
return (
<Stack.Navigator>
<Stack.Screen name="Main" component={() => <Main />} />
<Stack.Screen name="Data" component={() => <Data />} />
<Stack.Screen name="Grafic" component={() => <Grafic />} />
</Stack.Navigator>
);
}
const App = () => {
return (
<View style={{ flex: 1 }}>
<Header />
<NavigationContainer>
<MyStack />
</NavigationContainer>
<Footer />
</View>
);
}
const styles = StyleSheet.create({
header: {
backgroundColor: "#00BFFF",
height: 55
},
buttonPos: {
flex: 1,
flexDirection: 'row',
alignItems: "center",
justifyContent: "space-between",
padding: 7
},
conection: {
flex: 1,
flexDirection: 'row',
alignItems: "center",
justifyContent: "space-between",
padding: 7
}
});
export default App
What you need to do that is to use a Tab Navigator.
react-navigation v5 has 3 ways to do so:
createBottomTabNavigator
createMaterialBottomTabNavigator (very easy to customize)
createMaterialTopTabNavigator (with tabBarPosition: 'bottom')
Also you can customize the tabs by reading the documentation.
I made you a basic example using this last option:
import { SafeAreaView, View, Text, StyleSheet } from 'react-native'
import { NavigationContainer } from '#react-navigation/native'
import { createMaterialTopTabNavigator } from '#react-navigation/material-top-tabs'
import { createStackNavigator } from '#react-navigation/stack'
const Header = () => <View style={styles.header}><Text>Header title</Text></View>
const Main = () => <View style={styles.component}><Text>Main component</Text></View>
const Data = () => <View style={styles.component}><Text>Data component</Text></View>
const Grafic = () => <View style={styles.component}><Text>Grafic component</Text></View>
const footerConfig = {
tabBarPosition: 'bottom',
}
const Tabs = createMaterialTopTabNavigator()
const MyFooter = () => (
<Tabs.Navigator {...footerConfig}>
<Tabs.Screen name="Main" component={Main} />
<Tabs.Screen name="Data" component={Data} />
<Tabs.Screen name="Grafic" component={Grafic} />
</Tabs.Navigator>
)
const stackConfig = {
headerMode: 'none',
}
const Stack = createStackNavigator()
const MyStack = () => (
<Stack.Navigator {...stackConfig}>
<Stack.Screen name="Tabs" component={MyFooter} />
</Stack.Navigator>
)
export default () => (
<SafeAreaView style={styles.main}>
<Header />
<NavigationContainer>
<MyStack />
</NavigationContainer>
</SafeAreaView>
)
const styles = StyleSheet.create({
main: {
flex: 1,
},
header: {
height: 64,
width: '100%',
justifyContent: 'center',
alignItems: 'center',
},
component: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
})
EDIT:
You can use useNavigation hook inside your components. If you want to use your current configuration.
https://reactnavigation.org/docs/use-navigation/useNavigation
Also in order to send navigation props to components this:
<Stack.Screen name="Main" component={() => <Main />} />
should become:
<Stack.Screen name="Main" component={Main} />
// or
<Stack.Screen name="Main" component={props => <Main {...props} />} />
Go to you Main, Data, Grafic components and add {navigation} as your function parameter:
function Main({navigation}){
// rest of your codes
}
export default Main