How can I make these components navigate to another screen in react?

Viewed 750

I'm currently working on a react project that has a navigation page with widgets that navigate to various parts of the app. However, I'm not sure how to make them navigate to their appropriate screens.

Edit:

I have added more of the code in order to better illustrate what I am trying to do. enter image description here

import React from 'react';
import {View, FlatList, Text, TouchableOpacity, Dimensions} from 'react-native';
import LinearGradientScreen from './linearGradientScreen';
import Feather from 'react-native-vector-icons/Feather';
import FontAwesome from 'react-native-vector-icons/FontAwesome';
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
import Entypo from 'react-native-vector-icons/Entypo';
const CellComponent = (props) => {
  return (
    <TouchableOpacity
      onPress={() => props.navigation.navigate('tabNavigator')}
      style={{
        backgroundColor: props.item.color,
        height: (13 * Dimensions.get('window').height) / 100,
        width: 132,
        borderRadius: 5,
        shadowColor: 'rgba(52,2,2,1)',
        shadowOffset: {
          width: 3,
          height: 3,
        },
        elevation: 5,
        shadowOpacity: 1,
        shadowRadius: 0,
        margin: 20,
        alignItems: 'center',
        justifyContent: 'center',
      }}>
      {props.item.family === 'Feather' ? (
        <Feather
          type={props.item.type}
          color={'rgba(255,255,255,1)'}
          name={props.item.icon}
          size={30}
        />
      ) : null}
      {props.item.family === 'MaterialCommunityIcons1' ? (
        <MaterialCommunityIcons
          type={props.item.type}
          color={'rgba(255,255,255,1)'}
          name={props.item.icon}
          size={30}
        />
      ) : null}
      {props.item.family === 'Entypo' ? (
        <Entypo
          type={props.item.type}
          color={'rgba(255,255,255,1)'}
          name={props.item.icon}
          size={30}
        />
      ) : null}
      {props.item.family === 'MaterialCommunityIcons2' ? (
        <MaterialCommunityIcons
          type={props.item.type}
          color={'rgba(255,255,255,1)'}
          name={props.item.icon}
          size={30}
        />
      ) : null}
      {props.item.family === 'MaterialCommunityIcons' ? (
        <MaterialCommunityIcons
          type={props.item.type}
          color={'rgba(255,255,255,1)'}
          name={props.item.icon}
          size={30}
        />
      ) : null}
      {props.item.family === 'FontAwesome' ? (
        <FontAwesome
          type={props.item.type}
          color={'rgba(255,255,255,1)'}
          name={props.item.icon}
          size={30}
        />
      ) : null}
      <Text
        style={{
          color: 'white',
          fontSize: 18 * Dimensions.get('window').fontScale,
        }}>
        {props.item.name}
      </Text>
    </TouchableOpacity>
  );
};
const HomeScreen = (props) => {
  return (
    <LinearGradientScreen>
      <View style={{alignItems: 'center', justifyContent: 'center'}}>
        <Text
          style={{
            marginTop: '20%',
            fontSize: 50 * Dimensions.get('window').fontScale,
            color: 'white',
            fontWeight: 'bold',
          }}>
          Home
        </Text>
        <Text
          style={{
            fontSize: 25 * Dimensions.get('window').fontScale,
            color: 'white',
            fontWeight: '400',
            marginBottom: '10%',
          }}>
          Select a service
        </Text>
        <FlatList
          numColumns={2}
          data={HomeScreenData}
          renderItem={({item}) => {
            return <CellComponent {...props} item={item} />;
          }}
        />
      </View>
    </LinearGradientScreen>
  );
};
const HomeScreenData = [
  {
    id: 1,
    name: 'AI Chat',
    icon: 'cpu',
    family: 'Feather',
    color: 'rgba(247,52,122,1)',
  },
  {
    id: 2,
    name: 'Live Chat',
    icon: 'wechat',
    family: 'FontAwesome',
    color: 'rgba(16,165,245,1)',
  },
  {
    id: 3,
    name: 'Resources',
    icon: 'file-document-outline',
    family: 'MaterialCommunityIcons',
    color: 'rgba(74,74,74,1)',
  },
  {
    id: 1,
    name: 'Client Connect',
    icon: 'gesture-swipe-horizontal',
    family: 'MaterialCommunityIcons1',
    color: 'rgba(237,41,57,1)',
  },
  {
    id: 1,
    name: 'DM',
    icon: 'message',
    family: 'Entypo',
    color: 'rgba(74,144,226,1)',
  },
  {
    id: 1,
    name: 'Profile',
    icon: 'tooltip-account',
    family: 'MaterialCommunityIcons2',
    color: 'rgba(144,19,254,1)',
  },
];
export default HomeScreen;

Is there something like navigate: 'AiScreen.js', that I can use to make it navigate to the correct place?

2 Answers

Every Stack.Screen should receive the prop "name" to make it available on "navigation.navigate("RouteName")".

from the docs https://reactnavigation.org/docs/navigating/

import * as React from 'react';
import { Button, View, Text } from 'react-native';
    
    function HomeScreen({ navigation }) {
      return (
        <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
          <Text>Home Screen</Text>
          <Button
            title="Go to Details"
            onPress={() => navigation.navigate('Details')}
          />
        </View>
      );
    }
export default HomeScreen;

If you named your routes like in the docs

import * as React from 'react';
import { View, Text } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import DetailsScreen from "~/pages/Detail";
import HomeScreen from "~/pages/Home";

const Stack = createStackNavigator();

function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator "initialRouteName="Home"  >
        <Stack.Screen name="Details" component={DetailsScreen} />
        <Stack.Screen name="Home" component={HomeScreen} />

      </Stack.Navigator>
    </NavigationContainer>
  );
}

export default App;

Same way you have "initialRouteName="Home" on <Stack.Navigator/> component that matches with the name you passed to <Stack.Screen/> "name" props

Output:

enter image description here

Here is an example, here I have Implemented How you can navigate to the Ai Chat Screen, Just like that you can create other screens, define them in Stack Navigator and navigate within them.

import * as React from 'react';
import { Button, View, Text, FlatList } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import HomeScreen from './HomeScreen';

function AiChatScreen({ navigation }) {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Ai AiChatScreen</Text>
    </View>
  );
}

const Stack = createStackNavigator();

function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator initialRouteName="Home">
        <Stack.Screen name="Home" component={HomeScreen} />
        <Stack.Screen name="AI Chat" component={AiChatScreen} />
        <Stack.Screen name="Resources" component={ResourcesScreen} />
        <Stack.Screen name="DM" component={DmScreen} />
        <Stack.Screen name="Profile" component={ProfileScreen} />
        <Stack.Screen name="Live Chat" component={LiveChatScreen} />
        <Stack.Screen name="Client Connect" component={ClientConnectScreen} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

function LiveChatScreen({ navigation }) {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Live Chat Screen</Text>
    </View>
  );
}

function ResourcesScreen({ navigation }) {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Resources Screen</Text>
    </View>
  );
}

function ClientConnectScreen({ navigation }) {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Client Connect Screen</Text>
    </View>
  );
}

function DmScreen({ navigation }) {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>DM Screen</Text>
    </View>
  );
}

function ProfileScreen({ navigation }) {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Profile Screen</Text>
    </View>
  );
}

export default App;

Modified CellComponent, it takes props.item.name for routing.

So, you don't have to worry about typing the route name for each screen.

const CellComponent = (props) => {
  return (
    <TouchableOpacity
      onPress={() => props.navigation.navigate(props.item.name)}
      style={{
        backgroundColor: props.item.color,
        height: (13 * Dimensions.get('window').height) / 100,
        width: 132,
        borderRadius: 5,
        shadowColor: 'rgba(52,2,2,1)',
        shadowOffset: {
          width: 3,
          height: 3,
        },
        elevation: 5,
        shadowOpacity: 1,
        shadowRadius: 0,
        margin: 20,
        alignItems: 'center',
        justifyContent: 'center',
      }}>
      {props.item.family === 'Feather' ? (
        <Feather
          type={props.item.type}
          color={'rgba(255,255,255,1)'}
          name={props.item.icon}
          size={30}
        />
      ) : null}
      {props.item.family === 'MaterialCommunityIcons1' ? (
        <MaterialCommunityIcons
          type={props.item.type}
          color={'rgba(255,255,255,1)'}
          name={props.item.icon}
          size={30}
        />
      ) : null}
      {props.item.family === 'Entypo' ? (
        <Entypo
          type={props.item.type}
          color={'rgba(255,255,255,1)'}
          name={props.item.icon}
          size={30}
        />
      ) : null}
      {props.item.family === 'MaterialCommunityIcons2' ? (
        <MaterialCommunityIcons
          type={props.item.type}
          color={'rgba(255,255,255,1)'}
          name={props.item.icon}
          size={30}
        />
      ) : null}
      {props.item.family === 'MaterialCommunityIcons' ? (
        <MaterialCommunityIcons
          type={props.item.type}
          color={'rgba(255,255,255,1)'}
          name={props.item.icon}
          size={30}
        />
      ) : null}
      {props.item.family === 'FontAwesome' ? (
        <FontAwesome
          type={props.item.type}
          color={'rgba(255,255,255,1)'}
          name={props.item.icon}
          size={30}
        />
      ) : null}
      <Text
        style={{
          color: 'white',
          fontSize: 18 * Dimensions.get('window').fontScale,
        }}>
        {props.item.name}
      </Text>
    </TouchableOpacity>
  );
};

Working Example: Expo Snack

Related