Home > front end >  react-navigation child component data to parent component function [react-navigation 6]
react-navigation child component data to parent component function [react-navigation 6]

Time:12-12

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.

  1. Components
    • MealList
    • MealItem
  2. 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
               
       })}
  • Related