I’m working on a React Native app where I’m using React Navigation to navigate between screens. I have a Drawer component that contains a "Give me a Random Recipe!!" button. When the button is pressed, I want to navigate to the RecipeScreen and pass a random recipe object as well as its corresponding category and title.
However, I’m facing an issue where the category prop in the RecipeScreen is always undefined, even though I’m passing it correctly from the DrawerContainer. I have checked the logs, and the category is correctly logged in the DrawerContainer component before navigation.
I have simplified the relevant code snippets for both components below:
Drawer.js:
import React, { useEffect } from "react";
import { getCategoryById } from "../../data/API";
const Drawer = () => {
const navigation = useNavigation();
useEffect(() => {
// Fetch random recipe here if needed
}, []);
const handleNavigate = () => {
const randomRecipe = {}; // Replace with the random recipe object
const category = getCategoryById(randomRecipe.categoryID);
const title = category ? category.name : "";
navigation.navigate("Recipe", { item: randomRecipe, category, title });
navigation.closeDrawer();
};
return (
<View>
<MenuButton
title="Give me a Random Recipe!!"
onPress={handleNavigate}
/>
</View>
);
};
DrawerContainer.propTypes = {
navigation: PropTypes.shape({
navigate: PropTypes.func.isRequired,
closeDrawer: PropTypes.func.isRequired,
}),
};
export default DrawerContainer;
RecipeScreen.js:
export default function RecipeScreen(props) {
const { navigation, route } = props;
const category = route.params.category;
const title = item.title;
const [activeSlide, setActiveSlide] = useState(0);
const [recipeData, setRecipeData] = useState(null);
const slider1Ref = useRef();
useLayoutEffect(() => {
navigation.setOptions({
headerTransparent: true,
headerLeft: () => (
<BackButton
onPress={() => {
navigation.goBack();
}}
/>
),
headerRight: () => <View />,
});
}, []);
const renderImage = ({ item }) => (
<TouchableHighlight>
<View style={styles.imageContainer}>
<Image style={styles.image} source={{ uri: item }} />
</View>
</TouchableHighlight>
);
useEffect(() => {
fetch('http://10.11.55.7:111/rest', {
headers: {
'Content-Type': 'application/json'
}
})
.then(response => response.json())
.then(data => {
const matchedRecipe = data.find(recipe => recipe.recipeID === item.recipeId);
if (matchedRecipe) {
console.log(matchedRecipe.recipeID);
setRecipeData(matchedRecipe);
} else {
console.log('No matching recipe found');
}
})
.catch(error => {
console.log('Fetch error:', error);
// Handle the error here
});
}, []);
return (
<ScrollView style={styles.container}>
<View style={styles.carouselContainer}>
<View style={styles.carousel}>
<Carousel
ref={slider1Ref}
data={item.photosArray}
renderItem={renderImage}
sliderWidth={viewportWidth}
itemWidth={viewportWidth}
inactiveSlideScale={1}
inactiveSlideOpacity={1}
firstItem={0}
loop={false}
autoplay={false}
autoplayDelay={500}
autoplayInterval={3000}
onSnapToItem={(index) => setActiveSlide(0)}
/>
<Pagination
dotsLength={item.photosArray.length}
activeDotIndex={activeSlide}
containerStyle={styles.paginationContainer}
dotColor="rgba(255, 255, 255, 0.92)"
dotStyle={styles.paginationDot}
inactiveDotColor="white"
inactiveDotOpacity={0.4}
inactiveDotScale={0.6}
carouselRef={slider1Ref.current}
tappableDots={!!slider1Ref.current}
/>
</View>
</View>
<View style={styles.infoRecipeContainer}>
<Text style={styles.infoRecipeName}>{item.title}</Text>
<View style={styles.infoContainer}>
{category && (
<Text style={styles.category}>
{getCategoryName(item.categoryId).toUpperCase()}
</Text>
)}
</View>
</View>
</ScrollView>
);
}
I get an error on this line when switching screens:
{getCategoryName(item.categoryId).toUpperCase()}
because
const category = route.params.category;
is undefined when I switch from the drawer screen to the recipe screen.
I would greatly appreciate any insights or suggestions on how to correctly pass the category prop from Drawer to RecipeScreen. Thank you in advance!
2
Answers
The issue you’re facing is likely due to the fact that you’re trying to access the category prop in RecipeScreen using route.params.category, but it seems that you’re passing the category as a separate prop named category in your navigation.navigate call in the Drawer component.
To resolve this, you can modify your handleNavigate function in the Drawer component to pass the category prop directly instead of including it in the navigation.navigate call:
Then, in your RecipeScreen, you can access the category prop directly from route.params:
Make sure to double-check the correctness of your getCategoryName function and ensure that it returns the expected category name based on the provided categoryId.
By making these changes, you should be able to correctly access the category prop in your RecipeScreen component and display the category name.
You are passing the randomRecipe, category and title in the name of item from Drawer.js correctly, But, You have to change the props to access the prop in your RecipeScreen.js like this ,