Any help will be appreciated. I am using Expo React-Native with JavaScript and I have tried to create a bottom-button-bar for my app, but it causes my desired screen to present on top of my Home screen like that:
In this picture, the Orders screen takes the bottom of the screen while the home screen is still visible, even though I pressed the Orders button. I am not sure what is causing this issue. This is the related code of my home screen:
import React, { useState, useEffect } from "react";
import { StatusBar } from "expo-status-bar";
import { SafeAreaView, View, TouchableOpacity, Text, StyleSheet } from "react-native";
import { useNavigation } from "@react-navigation/native";
import colors from '../colors';
import { AntDesign, Feather } from "@expo/vector-icons";
import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
import ProductsList from "../components/ProductsList";
import { listenForProducts } from "../products";
import Profile from "./Profile";
import Orders from "./Orders";
const Home = () => {
const navigation = useNavigation();
const [products, setProducts] = useState({});
useEffect(() => {
const unsubscribe = listenForProducts((products) => {
setProducts(products);
});
return () => unsubscribe();
}, []);
const Tab = createBottomTabNavigator();
return (
<View style={styles.container}>
<View style={{ flex: 1 }}>
<SafeAreaView className="flex-1 items-center justify-center bg-gray-200">
<ProductsList products={products} />
<StatusBar style={"dark"} />
</SafeAreaView>
</View>
<Tab.Navigator tabBar={CustomTabBar}>
<Tab.Screen name="Profile" component={Profile} />
<Tab.Screen name="Orders" component={Orders} />
</Tab.Navigator>
</View>
);
};
const CustomTabBar = ({ state, descriptors, navigation }) => {
const getTabBarIcon = (name, focused) => {
switch (name) {
case "Profile":
return <AntDesign name="profile" size={24} color={focused ? colors.primary : colors.gray} />;
case "Orders":
return <Feather name="shopping-bag" size={24} color={focused ? colors.primary : colors.gray} />;
default:
return null;
}
};
return (
<View style={styles.tabBar}>
{state.routes.map((route, index) => {
const { options } = descriptors[route.key];
const label = options.title !== undefined ? options.title : route.name;
const isFocused = state.index === index;
const onPress = () => {
const event = navigation.emit({
type: 'tabPress',
target: route.key,
canPreventDefault: true,
});
if (!isFocused && !event.defaultPrevented) {
navigation.navigate(route.name);
}
};
return (
<TouchableOpacity
key={route.key}
accessibilityRole="button"
accessibilityState={isFocused ? { selected: true } : {}}
accessibilityLabel={options.tabBarAccessibilityLabel}
testID={options.tabBarTestID}
onPress={onPress}
style={styles.tabBarButton}
>
{getTabBarIcon(label, isFocused)}
<Text style={{ color: isFocused ? colors.primary : colors.gray }}>
{label}
</Text>
</TouchableOpacity>
);
})}
</View>
);
};
export default Home;
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#e5e5e5",
},
tabBar: {
flexDirection: 'row',
justifyContent: 'space-around',
alignItems: 'center',
backgroundColor: '#fff',
borderTopWidth: 1,
borderTopColor: colors.gray,
},
tabBarButton: {
alignItems: 'center',
paddingVertical: 10,
},
});
The issue was using createBottomTabNavigator as a navigator. This code fixed the issue:
import React, { useState, useEffect } from "react";
import { StatusBar } from "expo-status-bar";
import { SafeAreaView, View, TouchableOpacity, Text, StyleSheet } from "react-native";
import { useNavigation } from "@react-navigation/native";
import colors from '../colors';
import { AntDesign, Feather } from "@expo/vector-icons";
import ProductsList from "../components/ProductsList";
import { listenForProducts } from "../products";
const Home = () => {
const navigation = useNavigation();
const [products, setProducts] = useState({});
useEffect(() => {
const unsubscribe = listenForProducts((products) => {
setProducts(products);
});
return () => unsubscribe();
}, []);
return (
<View style={styles.container}>
<View style={{ flex: 1 }}>
<SafeAreaView className="flex-1 items-center justify-center bg-gray-200">
<ProductsList products={products} />
<StatusBar style={"dark"} />
</SafeAreaView>
</View>
<View style={styles.tabBar}>
<TabBarButton
label="Profile"
icon={<AntDesign name="profile" size={24} color={colors.primary} />}
onPress={() => navigation.navigate("Profile")}
/>
<TabBarButton
label="Orders"
icon={<Feather name="shopping-bag" size={24} color={colors.primary} />}
onPress={() => navigation.navigate("Orders")}
/>
</View>
</View>
);
};
const TabBarButton = ({ onPress, label, icon }) => (
<TouchableOpacity onPress={onPress} style={styles.tabBarButton}>
{icon}
<Text style={styles.tabBarLabel}>{label}</Text>
</TouchableOpacity>
);
export default Home;
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#e5e5e5",
},
tabBar: {
flexDirection: 'row',
justifyContent: 'space-around',
alignItems: 'center',
backgroundColor: '#fff',
borderTopWidth: 1,
borderTopColor: colors.gray,
},
tabBarButton: {
alignItems: 'center',
paddingVertical: 10,
},
tabBarLabel: {
color: colors.primary,
},
});