I want to navigate to another page using TouchableOpacity but failed

177 Views Asked by At

I want to navigate to another page using TouchableOpacity but failed Navigating to other pages with Tab.Navigator works correctly. I created after that TouchableOpacity. Which is located in the middle of the other buttons and it should navigate to the scanner page Here is my code:

import React from "react";
import { StyleSheet, TouchableOpacity } from "react-native";
import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
import { NavigationContainer } from "@react-navigation/native";
import { MaterialCommunityIcons } from "@expo/vector-icons";
import MainScreen from "./view/MainPage";
import ProfileScreen from "./view/ProfilePage";
import ScanScreen from "./view/ScanPage";

const Tab = createBottomTabNavigator();

const App = ({ navigation }) => {
  return (
    <>
      <NavigationContainer>
        <Tab.Navigator
          style={styles.tabBar}
          screenOptions={({ route }) => ({
            tabBarIcon: ({ focused, color, size }) => {
              let iconName;

              if (route.name === "main") {
                iconName = focused ? "home" : "home";
              } else if (route.name === "scan") {
                iconName = focused ? "qrcode-scan" : "qrcode-scan";
              } else if (route.name === "profile") {
                iconName = focused ? "account" : "account";
              }

              return (
                <MaterialCommunityIcons
                  name={iconName}
                  size={size}
                  color={color}
                />
              );
            },
            tabBarLabel: "",
            tabBarActiveTintColor: "#1573FE",
            tabBarInactiveTintColor: "gray",
          })}
        >
          <Tab.Screen
            name="main"
            component={MainScreen}
            options={{ headerShown: false }}
          />
         
          <Tab.Screen
            name="profile"
            component={ProfileScreen}
            options={{ headerShown: false }}
          />
        </Tab.Navigator>

        <TouchableOpacity
          style={styles.scanButton}
          onPress={() => navigation.navigate("ScanScreen")}
        >
          <MaterialCommunityIcons name="qrcode-scan" color="white" size={30} />
        </TouchableOpacity>
      </NavigationContainer>
    </>
  );
};

This is what the page where the TouchableOpacity navigate:

const ScanScreen = ({ navigation }) => {
  return (
    <View style={styles.screen}>
      <Text>This is the Scan screen</Text>
    </View>
  );
};

i just wanted to create a button enter image description here

do you know another way to create a round button?

6

There are 6 best solutions below

0
nativedev On BEST ANSWER

You need to pass a custom Button/Icon component to tabBarButton prop in options. That's how I handle it.

export const CustomTabBarButton = ({
  children,
  onPress,
}: {
  children: React.ReactNode;
  onPress: (e) => void;
}) => (
  <TouchableOpacity
    style={{
      top: -1,
      right: 9,
    }}
    onPress={onPress}
  >
    <View
      style={{
        width: 80,
        height: 80,
        borderRadius: 35,
        justifyContent: "center",
      }}
    >
      {children}
    </View>
  </TouchableOpacity>
);




  <Tab.Screen
    name={SCREEN_CONFIG.SEARCH}
    component={Search}
    options={{
      headerShown: false,
      title: SCREEN_CONFIG.SEARCH,
      tabBarLabelPosition: "below-icon",
      tabBarButton: props => (
        <CustomTabBarButton
          onPress={e => {
            props.onPress?.(e);
          }}
        >
          <View
            style={{
              backgroundColor: COLORS[theme].TAB_BAR_BG,
              borderRadius: 50,
              width: 100,
              height: 100,
              justifyContent: "center",
              alignItems: "center"
            }}
          >
            <PlusIcon />
          </View>
        </CustomTabBarButton>
      )
    }}
  />

enter image description here

5
NASIR ALI On
<TouchableOpacity onPress={() => navigate('/details')}>

{/* Your button content */}

1
Vasyl Nahuliak On

Create the custom component. Because navigation prop doesn't exist. You can get navigation only under NavigationContainer component.

import React from 'react';
import { TouchableOpacity } from 'react-native';

import { MaterialCommunityIcons } from '@expo/vector-icons';
import { useNavigation } from '@react-navigation/native';

export const Button = () => {
  const navigate = useNavigation();

  return (
    <TouchableOpacity
      style={styles.scanButton}
      onPress={() => navigate('ScanScreen')}>
      <MaterialCommunityIcons name="qrcode-scan" color="white" size={30} />
    </TouchableOpacity>
  );
};

1
Yilmaz On

navigation prop is passed to the screen components. you define the screen components inside the navigators. For example in your code, this is

    <Tab.Screen
        name="main"
        component={MainScreen}
        options={{ headerShown: false }}
      />

a screen component and MainScreen will receive navigation and you can navigate to another screen component. your app component does not receive navigation prop

 // this is just a custom component, not a screen component
 const App = ({ navigation }) => {}

Also, if you did not register the ScanScreen as a screen component inside a navigator, it will not receive navigation prop

// you have to register this as a screen component
const ScanScreen = ({ navigation }) => {
  return (
    <View style={styles.screen}>
      <Text>This is the Scan screen</Text>
    </View>
  );
};
1
Adnan Ashraf On

Check whether the name of the component is correctly spelled i.e ScanScreen is the same as in your routes file .Secondly check whether they both are in same stack .

2
Bala Vigness On

App component is not directly associated with the navigation stack, it doesn't have direct access to the navigation prop. To resolve this, you can wrap the App component with the NavigationContainer and move the TouchableOpacity inside the MainScreen component.

const App = () => {
  return (
    <NavigationContainer>
      <Tab.Navigator
        style={styles.tabBar}
        screenOptions={screenOptions}
      >
        <Tab.Screen
          name="main"
          component={MainScreen}
          options={{ headerShown: false }}
        />
        <Tab.Screen
          name="scan"
          component={ScanScreen}
          options={{ headerShown: false }}
        />
        <Tab.Screen
          name="profile"
          component={ProfileScreen}
          options={{ headerShown: false }}
        />
      </Tab.Navigator>
    </NavigationContainer>
  );
};

export default App;

MainScreen component, you can add the TouchableOpacity for scanning:

const MainScreen = ({ navigation }) => {
  return (
    <View style={styles.container}>
      <Text>Main Screen</Text>
      <TouchableOpacity
        style={styles.scanButton}
        onPress={() => navigation.navigate("scan")}
      >
        <MaterialCommunityIcons name="qrcode-scan" color="white" size={30} />
      </TouchableOpacity>
    </View>
  );
};