React-native-navigation navigate through a different component instead of from a page - react-native

My home page contains a View. This view contains a flat list with items. The flat list is being rendered through a different component
I should be able to use something like this.props.navigation.navigate('DetailPage') from the component not from my homePage.
I think i should pass the navigation as a prop to the but not sure how i could do that.
Navigation File
export const HomePageStack = StackNavigator({
Homepage:{
screen:homePage,
},
DetailPage:{
screen: DetailPage,
}
})
Home Page Screen
render(){
return(
<View>
<DetailedArea />
</View>
)}
Detailed Area
render(){
return(
<TouchableHighlight onPress={this.props.navigation.navigate('DetailPage')}>
<Text>CLICK HERE TO GO TO DETAIL PAGE</TEXT>
</TouchableHighlight>
)}

the HomeScreen has this.props.navigation, but it isn't passed down to DetailedArea.
I recommend the following:
HomeScreen
render(){
return(
<View>
<DetailedArea onNavigate={() => this.props.navigation.navigate('DetalPage')} />
</View>
)}
DetailedArea
render(){
return(
<TouchableHighlight onPress={this.props.onNavigate}>
<Text>CLICK HERE TO GO TO DETAIL PAGE</TEXT>
</TouchableHighlight>
)}

Related

TouchableOpacity link to another page and pass data React Native

Hi i am hitting to a problem. In the Homepage, I am creating a list of cards where show name, amount, and image, and those cards are created by another function from InfoCard.js.
Now I am not sure how to pass the data ( name, amount) and link to another page
Homepage:
import InfoCard from "../components/test";
const Home = ({ navigation }) => {
return (
{data.map((item, index) => (
<InfoCard {...item} key={index} />
))}
);
};
export default Home;
InfoCard js
export default InfoCard = ({ image, brand, amount }) => {
return (
<TouchableOpacity onPress={() => navigation.navigate("Detail")}>
<View style={externalStyle.home_company_list}>
<Image source={image} />
<View style={externalStyle.card}>
<Text style={externalStyle.home_company_text}>{brand}</Text>
<Text style={externalStyle.home_company_text}>{amount}</Text>
</View>
</View>
</TouchableOpacity>
);
};
Detail Page
Once the TouchableOpacity clicked from home page which created by InFoCard.js, will pass the data(brand,amount) to Detail page and display the data
You can pass it as params:
export default InfoCard = ({ image, brand, amount }) => {
return (
<TouchableOpacity onPress={() => navigation.navigate("Detail", {brand: brand,
amount: amount,})}>
<View style={externalStyle.home_company_list}>
<Image source={image} />
<View style={externalStyle.card}>
<Text style={externalStyle.home_company_text}>{brand}</Text>
<Text style={externalStyle.home_company_text}>{amount}</Text>
</View>
</View>
</TouchableOpacity>
);
};
And get it in details as:
this.props.navigation.state.params.brand,
this.props.navigation.state.params.amount
You can simply pass the parameter after the "Detail" Route name.
Take a look here: https://reactnavigation.org/docs/params/

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
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

componentWillMount doesn't get called again when navigating back to my original component

screen A: calling componentWillMount successfully and then navigating to screen B,
screen B: do some redux changes (that will affect the data in WillMount) and then navigating back to A but componentWillMount doesn't get called and preventing desirable data from appearing on the screen
screen A:
componentWillMount(){
this.props.fetchData();
console.log('fetched')
}
renderItem({item}){
return <Text>{item.name}</Text>
}
render(){
const array = Object.values(this.props.data)
return(
<View style={{flex: 1}}>
<Inline>
<View style={styles.container}>
<View style={styles.headerContainer}>
<Header style={styles.header} HeaderText={'EmployeeList'}
/>
</View>
<TouchableOpacity style={styles.buttonContainer}
onPress={()=> this.props.navigation.navigate('CreateEmp')}
//screen B
>
<Text style={styles.buttonStyle}>Add an Employee</Text>
</TouchableOpacity>
</View>
</Inline>
<FlatList
data={array}
renderItem={this.renderItem}
keyExtractor={array1 => array1.name}
/>
</View>
screen B:
functionOne(){
const {name, phone, createEmployee, shift} = this.props
createEmployee(name, phone, shift)
}
functionTwo(){
this.props.navigation.navigate('EmployeeList')//screen A
}
functionCombined(){
this.functionOne();
this.functionTwo();
}
and calling functionCombined in the class of course
The componentWillMount is executed when the screen is rendered.
However, when navigating to the Navigate command, if the screen is first moved, it is rendered to draw the screen, but if it is already rendered, it is not rendered again.
The function shall be moved using a push commands to run again.
functionTwo(){
this.props.navigation.push('EmployeeList')//screen A
}

how to navigate from nested component to other component react native?

i have a component in which on button click i render a component
<View style={styles.container}>
<Text> in Default component!</Text>
<Button title="add"
onPress={this.handelSubmit} />
{items.map((item, index) => (
<Home key={index} data={index} />))}
</View>
and my home component look like
<View style={styles.container}>
<Text onPress={() => { this.props.navigation.navigate("Calculator")}}>Semester {this.props.data +1}</Text>
</View>
onPress event i want to navigate to other screen i.e 'Calculator.js' but i got an error
i am using react-navigation for navgation
If you want to navigate from a component, you have to use your component like this:
<Home key={index} data={index} navigation={this.props.navigation} />

How to call function in a screen from another screen using Actions in react native router flux

Hi I have 2 page in my Project .When I go from the first page to the second page (using Action), then I return to the First page with the command Action.pop() ,At this time I want to call function in first page, how can I do it?
in first page :
.....
BacktoFirstPage(){
//my code
}
render(){
return(
<TouchableOpacity onPress={()=>Actoin.secondPage()}>
<Text>go to second page</Text>
</TouchableOpacity>
)
.....
in second page:
render(){
return(
<TouchableOpacity onPress={()=>Actoin.pop()}>
<Text>back to first page</Text>
</TouchableOpacity>
)
}
now , how to call BacktoFirstPage
What you can do is to pass the function you want to run as a parameter to next screen and then run it before pop the screen.
Example
....
BacktoFirstPage(){
//my code
}
render(){
return(
<TouchableOpacity onPress={()=>Actoin.secondPage({onPop: this.BacktoFirstPage.bind(this)})}>
<Text>go to second page</Text>
</TouchableOpacity>
)
.....
render(){
return(
<TouchableOpacity onPress={()=>{ this.props.onPop(); Actoin.pop()}>
<Text>back to first page</Text>
</TouchableOpacity>
)
}
OR
componentWillUnmount() {
this.props.onPop();
}
render(){
return(
<TouchableOpacity onPress={()=>{ Actoin.pop()}>
<Text>back to first page</Text>
</TouchableOpacity>
)
}