Reputation: 33
I have a parent functional component Layout which needs props to have access to it's children. However, as I am using navigation 5.x, I also need to pass navigation but what I have tried hasn't worked yet. Here is my work
import { Container, Header, Content, Left, Right } from 'native-base';
import React from 'react';
import { View } from 'react-native';
import Icon from 'react-native-vector-icons/FontAwesome';
import { useNavigation } from '@react-navigation/native';
const Layout = (props, navigation) => {
return (
<Container >
<Header style={{ alignItems: 'center', backgroundColor: '#3a455c', height: 50 }}>
<Left style={{ flexDirection: 'row' }}>
<MaterialIcon style={{ color: 'white', marginRight: 10 }} onPress={ () => console.log(navigation) } size={30} color="black" name= 'menu' />
</Left>
<Icon onPress={ () => navigation.navigate('Index') } size={20} style={{marginTop: 4, marginLeft: 130}} color="white" name= 'home' />
<Right style={{ flexDirection: 'row' }}>
<Icon onPress={ () => navigation.navigate('Index') } size={20} style={{marginTop: 4}} color="green" name= 'user' />
</Right>
</Header>
<Content >
<View>
{ props.children }
</View>
</Content>
</Container>
);
}
export default Layout;
Layout component is being rendered in Newsletter component
function Newsletter() {
const navigation = useNavigation();
return (
<Layout >
<ScrollView style={{ marginTop: 40, marginLeft: 12 }}>
<Text style={{fontSize: 24, fontFamily: 'sans-serif-medium', textAlign: 'center', fontWeight: 'bold'}} > Directed Distraction </Text>
<View>
<Text style={{ marginTop: 12, fontSize: 18, textAlign: 'left', fontStyle: 'italic' }}>
Elon Reeve Musk FRS (/ˈiːlɒn/; born June 28, 1971) is an engineer,
industrial designer, technology entrepreneur and philanthropist.
He is a citizen of South Africa, Canada, and the United States.
He is based in the United States, where he immigrated to at age 20 and
has resided since. He is the founder, CEO and chief engineer/designer
of SpaceX; early investor, CEO and product architect of Tesla,
Inc.; founder of The Boring Company; co-founder of Neuralink; and
co-founder and initial co-chairman of OpenAI. He was elected a Fellow of
the Royal Society (FRS) in 2018. In December 2016, he was ranked 21st
on the Forbes list of The World's Most Powerful People, and was ranked
joint-first on the Forbes list of the Most Innovative Leaders of 2019.
A self-made billionaire, as of July 2020 his net worth was estimated at $44.9
billion and he is listed by Forbes as the 22nd-richest person in the world.
He is the longest tenured CEO of any automotive manufacturer globally.
</Text>
<Button title="a" onPress={ () => console.log(navigation) }></Button>
</View>
</ScrollView>
</Layout>
);
}
navigation is printed just as an object{}. Help would be appreciated.
Upvotes: 1
Views: 772
Reputation: 1189
I will explain something first: the navigation
object gets passed to the prop object when this component rendered as a screen for any navigator and not next to it
so you can do a couple of things now
1- const Layout = (props)
and you can access the navigation
like how you access the children
like this props.navigation.navigate('Index')
2- or you can simply destructure anything you want from the props
object like this: const Layout = ({children, navigation}) => {
this way you can type less as you don't have to reference the props object anymore and it will be navigation.navigate('Index')
3- if your component does not rendered by a navigator
, then the navigation object
will not be passed to the prop object
and it will be undefined -- in this case there is a simple solution you can do and it's not the only solution:
I see that you already importing useNavigation
and useNavigation
exposes the navigation object
out of the box for you, so what you can do inside your component is: const navigation = useNavigation()
then you can use navigation
as always, but don't forget to remove the navigation
from the component parameters
here you can find more details about the useNavigation hook
useNavigation
4- here I will add the code for the layout component which I believe it should work
import { Container, Header, Content, Left, Right } from 'native-base';
import React from 'react';
import { View } from 'react-native';
import Icon from 'react-native-vector-icons/FontAwesome';
import { useNavigation } from '@react-navigation/native';
const Layout = (props) => {
const navigation = useNavigation();
return (
<Container >
<Header style={{ alignItems: 'center', backgroundColor: '#3a455c', height: 50 }}>
<Left style={{ flexDirection: 'row' }}>
<MaterialIcon style={{ color: 'white', marginRight: 10 }} onPress={ () => console.log(navigation) } size={30} color="black" name= 'menu' />
</Left>
<Icon onPress={ () => navigation.navigate('Index') } size={20} style={{marginTop: 4, marginLeft: 130}} color="white" name= 'home' />
<Right style={{ flexDirection: 'row' }}>
<Icon onPress={ () => navigation.navigate('Index') } size={20} style={{marginTop: 4}} color="green" name= 'user' />
</Right>
</Header>
<Content >
<View>
{ props.children }
</View>
</Content>
</Container>
);
}
export default Layout;
there other options like passing a handler to onPress and executing this function from the component where has access to the navigation object
I hope this is useful to you. let me know if it works
Upvotes: 2