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
I think it is because you need to move your
renderItem
function inside theApp
function sinceuseNavigation
is not allowed to use out of React component:1.
export default function App() {
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 passingitem.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.
Remove the screen, and just do a simple switch case inside the render item to determine to which screen you want to navigate to.