skip to Main Content

I’d tried to navigate screens via flatlist items but couldn’t succeed. This is my code that gives an error. Flatlist has two element which is image, text so I want to make them for navigation to go other screens. I’d tried lots of things but couldn’t do it. Is there any possibility to do it?

App.js

import { StatusBar } from 'expo-status-bar';
import { StyleSheet, Text, View, Image, FlatList, Pressable } from 'react-native';
import { useNavigation } from '@react-navigation/native';


// Screens
import AracScreen from './src/screens/arac';
import ServisScreen from './src/screens/servis';
import MobilScreen from './src/screens/mobil';
import ZimmetScreen from './src/screens/zimmet';
import ToplantiScreen from './src/screens/toplanti';
import MuhaberatScreen from './src/screens/muhaberat';
import IkramScreen from './src/screens/ikram';
import UyduOfisScreen from './src/screens/uyduofis';
import BizCafeScreen from './src/screens/bizcafe';
import TimePortalScreen from './src/screens/timeportal';


// Menu
const MenuData = [
  {id:1,title:'Araç',image:require('./src/images/car.png'),screen: AracScreen},
  {id:2,title:'Servis',image:require('./src/images/bus.png'),screen: ServisScreen},
  {id:3,title:'Mobil',image:require('./src/images/mobile.png'),screen: MobilScreen},
  {id:4,title:'Zimmet',image:require('./src/images/inventory2.png'),screen:ZimmetScreen},
  {id:5,title:'Toplantı',image:require('./src/images/meeting.png'),screen:ToplantiScreen},
  {id:6,title:'Muhaberat',image:require('./src/images/cargo.png'),screen:MuhaberatScreen},
  {id:7,title:'İkram Talebi',image:require('./src/images/snacks.png'),screen:IkramScreen},
  {id:8,title:'Uydu Ofisler',image:require('./src/images/outer_office.png'),screen:UyduOfisScreen},  
  {id:9,title:'BizCafe',image:require('./src/images/bizcafe.png'),screen:BizCafeScreen},
  {id:10,title:'TimePortal',image:require('./src/images/timeportal.png'),screen:TimePortalScreen},
  {id:11,title:'İSG',image:require('./src/images/safety.png')},
  {id:12,title:'Hakkımızda',image:require('./src/images/about-us.png')},
  {id:13,title:'Öneri Talep',image:require('./src/images/request.png')},
  {id:14,title:'İstatistikler',image:require('./src/images/statics.png')},
  {id:15,title:'Duyurular',image:require('./src/images/announce.png')},
]

const renderItem = ({item}) => {

  const navigation = useNavigation();

  const handlePress = () => {
    if (item.screen) {
      navigation.navigate(item.screen);
    } else {
      console.log("Hedef ekran belirtilmemiş.");
    }
  };

  return (
    <View style={styles.item}>
      <Pressable onPress={handlePress}>
        <Image source={item.image} style={styles.image}/>
        <Text style={styles.text}>{item.title}</Text>
      </Pressable>
    </View>
  )
};


export default function App() {
  
  return (
    <View style={styles.container}>
      <View style={styles.header}>
        <Image source={require('./src/images/logo-id.png')} style={{width:242, height:73, borderWidth:0}} alt='İdari İşler Dijital Platformu'/>
      </View>

      <View style={styles.body}>
          <View style={styles.appmenu}>
            <FlatList
              data={MenuData}
              numColumns={3}
              renderItem={renderItem}
              keyExtractor={(item) => item.id.toString()}
            />
          </View>
      </View>

      <View style={styles.footer}>
        <Image source={require('./src/images/app-footer.png')} style={{width:100, height:40, borderWidth:0}} alt='Doğuş Teknoloji'/>
      </View>


      <StatusBar style="auto" />
    </View>
  );  
}

Error

Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://react.dev/link/invalid-hook-call for tips about how to debug and fix this problem.

Thanks in advance.

2

Answers


  1. I think it is because you need to move your renderItem function inside the App function since useNavigation is not allowed to use out of React component:

    export default function App() {
    
        const renderItem = ({item}) => {
        
          const navigation = useNavigation();
        
          const handlePress = () => {
            if (item.screen) {
              navigation.navigate(item.screen);
            } else {
              console.log("Hedef ekran belirtilmemiş.");
            }
          };
        
          return (
            <View style={styles.item}>
              <Pressable onPress={handlePress}>
                <Image source={item.image} style={styles.image}/>
                <Text style={styles.text}>{item.title}</Text>
              </Pressable>
            </View>
          )
        };
      
        return (
        <View style={styles.container}>
          <View style={styles.header}>
            <Image source={require('./src/images/logo-id.png')} style={{width:242, height:73, borderWidth:0}} alt='İdari İşler Dijital Platformu'/>
          </View>
        
          <View style={styles.body}>
              <View style={styles.appmenu}>
                <FlatList
                  data={MenuData}
                  numColumns={3}
                  renderItem={renderItem}
                  keyExtractor={(item) => item.id.toString()}
                />
              </View>
          </View>
        
          <View style={styles.footer}>
            <Image source={require('./src/images/app-footer.png')} style={{width:100, height:40, borderWidth:0}} alt='Doğuş Teknoloji'/>
          </View>
        
        
          <StatusBar style="auto" />
        </View>
        );  
    }
    
    Login or Signup to reply.
  2. 1.

    export default function App() {

        const navigation = useNavigation(); // add here
    
        const renderItem = ({item}) => {
        
          // const navigation = useNavigation(); remove from here
        
          const handlePress = () => {
            if (item.screen) {
              navigation.navigate(item.screen);
            } else {
              console.log("Hedef ekran belirtilmemiş.");
            }
          };
    

    2.

    navigation.navigate takes ‘string’ as a parameter to which screen you want to navigate that is defined in your navigator. In your example you’re passing item.screen which is an import, try to use the screen you have set to <Stack.Screen name='the-string-you-need-to-use' component='ScreenImport'/>

    3. There is no need to have an array of imported screens.

      {id:1,title:'Araç',image:require('./src/images/car.png'),screen: AracScreen}
    

    Remove the screen, and just do a simple switch case inside the render item to determine to which screen you want to navigate to.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search