Search code examples
javascriptreact-nativeexpobottomtabs

React Native JavaScript another screen is visible on top of the current screen


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:

enter image description here

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


Solution

  • 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,
      },
    });