I am developing a Meals App refering to a React Native - The Practical Guide [2023] course in Udemy. While using a native route prop i am facin with the mentioned error i.e can't find itemData Can some help me to figure out where this code is going wrong.
CategoriesScreen.js
import { FlatList, StyleSheet } from "react-native";
import { CATEGORIES } from "../data/dummy-data";
import CategoryGridTile from "../components/CategoryGridTile";
function CategoriesScreen({ navigation }) {
function pressHandler() {
navigation.navigate("Meals Overview", { categoryId: itemData.item.id, });
}
function renderCategoryItem(itemData) {
return (
<CategoryGridTile
title={itemData.item.title}
color={itemData.item.color}
onPress={pressHandler}
/>
);
}
return (
<FlatList
data={CATEGORIES}
keyExtractor={(item) => item.id}
renderItem={renderCategoryItem}
numColumns={2}
/>
);
}
export default CategoriesScreen;
MealsOverviewScreen
import { View,Text,StyleSheet } from "react-native";
import {MEALS} from "../data/dummy-data"
function MealsOverviewScreen({route}){
const catId=route.params.categoryId;
return(
<View style={styles.container}>
<Text>Meals Overview Screen - {catId}</Text>
</View>
)
}
export default MealsOverviewScreen;
const styles=StyleSheet.create(
{
container:{
flex:1,
padding:16,
}
}
)
CategoryGridTile.js
import { Pressable, View, Text, StyleSheet, Platform } from "react-native";
function CategoryGridTile({ title, color,onPress}) {
return (
<View style={styles.gridItem}>
<Pressable
style={({ pressed }) => [styles.buttonStyle,pressed?styles.buttonPressed:null,]}
android_ripple={{ color: "#ccc" }}
onPress={onPress}
>
<View style={[styles.innerContainer,{backgroundColor:color }]}>
<Text style={styles.title}>{title}</Text>
</View>
</Pressable>
</View>
);
}
export default CategoryGridTile;
const styles = StyleSheet.create({
gridItem: {
flex: 1,
margin: 16,
height: 150,
borderRadius: 8,
elevation: 4,
backgroundColor: "white",
shadowColor: "black",
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.25,
shadowRadius: 8,
overflow: Platform.OS == "android" ? "hidden" : "visible",
},
buttonPressed: {
opacity: 0.25,
},
buttonStyle: {
flex: 1,
},
innerContainer: {
flex: 1,
padding: 16,
borderRadius:8,
alignItems: "center",
justifyContent: "center",
},
title: {
fontSize: 18,
fontWeight: "bold",
},
});
CodePudding user response:
It seems that the error is caused by the pressHandler
function being defined outside of the renderCategoryItem
function, so itemData
is not in the scope of pressHandler
and not defined. To fix this, you can move the pressHandler
function inside of renderCategoryItem
and pass itemData
as an argument:
function renderCategoryItem(itemData) {
function pressHandler() {
navigation.navigate("Meals Overview", { categoryId: itemData.item.id });
}
return (
<CategoryGridTile
title={itemData.item.title}
color={itemData.item.color}
onPress={pressHandler}
/>
);
}
Also, you can use the onPress prop on the CategoryGridTile component directly, and pass the callback function that calls the navigation, passing the itemData.item.id as parameter, like this:
function renderCategoryItem(itemData) {
return (
<CategoryGridTile
title={itemData.item.title}
color={itemData.item.color}
onPress={() => navigation.navigate("Meals Overview", { categoryId: itemData.item.id })}
/>
);
}
This way, you will have a cleaner code, and you will avoid an unnecessary function.