tomasxboda
tomasxboda

Reputation: 539

Navigate to a screen of parent navigator from child navigator screen

I am new to React Native and I have been building a simple Food Recipe app. My main Stack Navigator contains two screens: Bottom Tab Navigator and Recipe screen. I am in Home screen in the Tab Navigator and when I press any recipe, I want to pass recipe props and navigate to Recipe screen in the main Stack Navigator. Unfortunately, I haven't found any solution to this. Could you please help me solve this?

This is the main file App.js

const Navigator = createBottomTabNavigator(
  {
    Home: Home,
    Add: Add,
    Profile: Profile
  }
);

const Stack = createStackNavigator(
  {
    Navigator: Navigator,
    Recipe: Recipe
  },
  {
    headerMode: "none",
    navigationOptions: {
        headerVisible: false,
    }
  }
);

export default createAppContainer(Stack)

This is my Home Screen class

export default class Home extends Component {
    render() {
        return (
            <SafeAreaView style={styles.container}>
                <View style={styles.header}>
                    <Text style={styles.headerTitle}>Recipes</Text>
                </View>

                <ScrollView style={styles.categoryContainer}>
                    <Category name={"All Foods"} recipes={recipes} />
                    <Category name={"Meat"} recipes={[ recipes[1], recipes[3] ]} />
                    <Category name={"Vegetarian"} recipes={[ recipes[0], recipes[2] ]} />
                    <Category name={"Desserts"} recipes={[ recipes[4] ]} />
                </ScrollView>
            </SafeAreaView>
        )
    }
}

This is the Category class

export default class Category extends Component {
    render() {
        return (
            <View style={styles.container}>
                <View style={styles.categoryHeader}>
                    <Text style={styles.categoryHeaderTitle}>{this.props.name}</Text>
                </View>

                <ScrollView >
                    <View style={styles.categoryContent}>
                        <FlatList
                            data={this.props.recipes}
                            renderItem={({ item }) => <Block name={item.name} image={item.image} time={item.time} portions={item.portions} />}
                            keyExtractor={(item, index) => index.toString()}
                            horizontal={true}
                        /> 
                    </View>  
                </ScrollView>
            </View>
        )
    }
}

This is the actual recipe block where I want to navigate all the way back to the Recipe screen and pass recipe props using onPress={} function

export default class Block extends Component {
    render() {
        return (
            <TouchableOpacity style={styles.container} onPress={null} >
                <Image style={styles.image} source={this.props.image} />

                <Text style={styles.title}>{this.props.name}</Text>
                <Text style={styles.info}>{this.props.time} min | portions: {this.props.portions}</Text>
            </TouchableOpacity>
        )
    }
}

Thank you for all your answers

Upvotes: 1

Views: 2149

Answers (1)

Auticcat
Auticcat

Reputation: 4489

If you need the StackNavigator to display a header on top of a BottomTabNavigator i would suggest to use a StackNavigator for every child of the bottomTabBar. Doing like that you can have more screens in a single tabBarItem, and you won't have the bottomTabBar disappearing for the other screens.

If you don't mind of this, you can access your stackNavigator from his child using dangerouslyGetParent and then navigate with the props you need.

navigateToRecipe = (recipe) => {
   this.props.navigation.dangerouslyGetParent().navigate("Recipe", { recipe : myRecipe}) //pass an object with the data you need
}

Then you can access your recipe props either using getParam this.props.navigation.getParam("recipe") or directly using this.props.navigation.state.params

Upvotes: 1

Related Questions