my Senario is that I have multiple screens (CategoriesScreen, CategoryMealsScreen, MealDetailsScreen, Favorites Screen). I want to outsource my meal items into a separate component and reuse the component in both the CategoryMealsScreen and Favorites Screen.
- Components
- MealList
- MealItem
- Screens
- CategoriesScreen
- CategoryMealsScreen
- MealDetailsScreen
- Favorites Screen
first User choose a Category in CategoriesScreen then with the code
props.navigation.navigate('CategoryMeals',
{categoryId: itemData.item.id}
the CategoryMealsScreen receive categoryId
catId = props.route.params.categoryId;
now I want to navigate to child component from Parent CategoryMealsScreen.js . Is the code correct?
return <MealList listData={displayedMeals} navigation = {props.navigation} />;
and then in MealList navigate to MealDetailsScreen
onSelectMeal={() => {
props.navigation.navigate({
routeName: 'MealDetail',
params: {
mealId: itemData.item.id
}
});
Error: You need to specify name or key when calling navigate with an object as the argument. See https://reactnavigation.org/docs/navigation-actions#navigate for usage after click on CategoryMealsScreen error occure and cannot show MealDetailsScreen.
import React from 'react';
import { View, Text, FlatList, StyleSheet, TouchableOpacity } from 'react-native';
import { CATEGORIES } from '../data/dummy-data';
import Colors from '../constants/Colors';
import CategoryGridTile from '../components/CategoryGridTile'
const CategoriesScreen = props =>
{
const renderGridItem = itemData => {
return (
<CategoryGridTile
title={itemData.item.title}
color={itemData.item.color}
onSelect = {() => {
props.navigation.navigate('CategoryMeals',
{categoryId: itemData.item.id}
);
}}
/>
);
};
return (
<FlatList
keyExtractor={(item, index) => item.id}
data={CATEGORIES}
renderItem={renderGridItem}
numColumns={2}
/>
);
};
....
export default CategoriesScreen;
************************************
import React from 'react';
import {View, Text, Button, FlatList} from 'react-native';
import {CATEGORIES , MEALS} from '../data/dummy-data';
import MealList from '../components/MealList';
const CategoryMealsScreen = props =>{
const catId = props.route.params.categoryId;
const displayedMeals = MEALS.filter(meals => meals.categoryIds.indexOf(catId) >= 0 );
//I think the error is for this line
return <MealList listData={displayedMeals} navigation = {props.navigation} />;
};
CategoryMealsScreen.navigationOptions = navigationData => {
const catId = navigationData.navigation.getParam('categoryId');
const selectedCategory = CATEGORIES.find(cat => cat.id === catId);
return {
headerTitle: selectedCategory.title,
};
};
export default CategoryMealsScreen
***********************************
import React from 'react';
import { View, FlatList, StyleSheet } from 'react-native';
import MealItem from './MealItem';
const MealList = props => {
const renderMealItem = itemData => {
return (
<MealItem
title={itemData.item.title}
image={itemData.item.imageUrl}
duration={itemData.item.duration}
complexity={itemData.item.complexity}
affordability={itemData.item.affordability}
onSelectMeal={() => {
props.navigation.navigate({
routeName: 'MealDetail',
params: {
mealId: itemData.item.id
}
});
}}
/>
);
};
return (
<View style={styles.list}>
<FlatList
data={props.listData}
keyExtractor={(item, index) => item.id}
renderItem={renderMealItem}
style={{ width: '100%' }}
/>
</View>
);
};
const styles = StyleSheet.create({
list: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
padding: 15
}
});
export default MealList;
-------------------------------------------------
import React from 'react';
import { View, Text, Button, StyleSheet } from 'react-native';
import { HeaderButtons, Item } from 'react-navigation-header-buttons';
import { MEALS } from '../data/dummy-data';
import HeaderButton from '../components/HeaderButton';
const MealDetailScreen = props => {
const mealId = props.route.params.mealId;
const selectedMeal = MEALS.find(meal => meal.id === mealId);
return (
<View style={styles.screen}>
<Text>{selectedMeal.title}</Text>
<Button
title="Go Back to Categories"
onPress={() => {
props.navigation.popToTop();
}}
/>
</View>
);
};
MealDetailScreen.navigationOptions = navigationData => {
const mealId = navigationData.navigation.getParam('mealId');
const selectedMeal = MEALS.find(meal => meal.id === mealId);
return {
headerTitle: selectedMeal.title,
headerRight: (
<HeaderButtons HeaderButtonComponent={HeaderButton}>
<Item
title="Favorite"
iconName="ios-star"
onPress={() => {
console.log('Mark as favorite!');
}}
/>
</HeaderButtons>
)
};
};
const styles = StyleSheet.create({
screen: {
flex: 1,
justifyContent: 'center',
alignItems: 'center'
}
});
export default MealDetailScreen;
If you have any ideas, please share them.
CodePudding user response:
For example,You have stack screen like this.
<Stack.Screen name="MealDetailsScreen" component={MealDetailsScreen} />
You should try the name of screen to navigate. like,
onSelectMeal={() =>
props.navigation.navigate(
'MealDetailsScreen',
{
mealId: itemData.item.id
})}