React native: How to navigate nested navigator (wrapped by a component) - react-native

I read on the docs about navigating nested navigator https://reactnavigation.org/docs/en/navigation-actions.html#setparams
const navigateAction = NavigationActions.navigate({
routeName: 'Profile',
params: {},
action: NavigationActions.navigate({ routeName: 'SubProfileRoute'})
})
this.props.navigation.dispatch(navigateAction)
However, my nested navigator SubProfileRoute is wrapped by a component
module.exports = class _ extends React.Component { ... }
not
module.exports = StackNavigator({})
So how do i do it?

You'll need to assign the router of the child navigator to the component wrapping it - that way the outer navigator will pass the navigation property to the child navigator.
See explicitly rendering more than one navigator.

So, I managed to solve this problem on my side. The issue is the links shared here don't work, even though Kraylog's answer provides a good place to start the research.
I found that, in order for nested routers to work, the navigation does indeed look for a child router in the component that it renders. However, it's not enough to set the router property to a child router's for everything to work with, in my example, redux navigation.
You also need to pass the navigation prop manually to the child navigator.
The documentation that helped a bit is this custom navigator guide.
The solution ended up being a simple one:
class MyNavigator extends React.Component {
static router = NestedNavigator.router;
render() {
return <NestedNavigator navigation={this.props.navigation} />;
}
}

Related

Rendering a TabNavigator in Storybook

I want to use Storybook.js to mock up a page that utilizes createMaterialTopTabNavigator(). However I can't render the material Tab because the output of the function is not actually a react component. So when I directly tried <TabNavigator /> it threw an invariant violation that "navigation" was missing. The only work-around I found was using createAppContainer() around the TabNavigator. But I know that it is bad practice to use more than one navigator. Is there any way to render a react navigator element without needing the navigation container?
This is my current working code for the storybook:
const tabConfiguration = {
Old: {
screen: OldProductsScreen,
navigationOptions: {
title: "Old"
}
},
New: {
screen: NewProductsScreen,
navigationOptions: {
title: "New"
}
}
};
const TabNavigator = createMaterialTopTabNavigator(tabConfiguration);
storiesOf('Test', module)
.add('Initial', () => {
const TAB = createAppContainer(TabNavigator);
return (
<TAB / >
);
})
;
I know that it is bad practice to use more than one navigator. Is there any way to render a react navigator element without needing the navigation container?
It's bad practice to do that in an app. But since you're using Storybook where each container is in like its own independent app, this is totally fine.

How to Create Drawer menu without Navigation?

I am looking to create a drawer, similar to a drawer navigator, but without the routes/navigation requirement.
I plan on placing some other components there that update a query. Any recommendations? Specifically the drawer would be used to display picklists, sliders, and date range components that would update the state and variables used in updating markers rendered on a map shown on the home page.
With Redux
You can use the contentComponent of the createDrawerNavigator to create your own custom drawer and bind it to redux-store.
By dispatching the actions with relevant queries you can update the variables as they are passed from the store to your Component.
Without Redux
You can either create a CustomDrawer component with similar animation and render it in your Component or use this react-native-drawer.
import Drawer from 'react-native-drawer'
class Application extends Component {
closeControlPanel = () => {
this._drawer.close()
};
openControlPanel = () => {
this._drawer.open()
};
render () {
return (
<Drawer
ref={(ref) => this._drawer = ref}
content={<DrawerContentComponent {...// Your Updater props}/>}
>
<Component />
</Drawer>
)
}
})

props automaticaly given as parameter

I would like to use a custom component and I need it to have the navigation props in order to navigate inside this component.
For now I'm passing navigation as a classic prop:
<MyVideo videoSource={require('../Image/S01E01DB.mp4')}
thumbnailSource={require('../Image/S01E01DB.mp4')}
navigation={this.props.navigation}/>
But is it possible to always have him set as it was given as a prop?
I need that in order to simplify the usage of my prop.
As said in the comments section by #jonrsharpe, the navigation props is only automatically given to routes declared with createStackNavigator or the others react-navigationnavigators`
There's a tool you can use from react-navigation to connect any component to your parent navigator:
import { withNavigation } from 'react-navigation';
class MyBackButton extends React.Component {
render() {
return <Button title="Back" onPress={() => { this.props.navigation.goBack() }} />;
}
}
// withNavigation returns a component that wraps MyBackButton and passes in the
// navigation prop
export default withNavigation(MyBackButton);
In case of nested navigators, the withNavigation function will get the closest parent of your component.
You will find more informations on this link

React Navigation(v2) How to pass props to my TabNavigator and send those props to a screen

I am new to React-Native and React. I am trying to implement a simple Tab Navigation on my mobile app using React Navigation (v2)
Basically there are two files:
Router.js
// imports...
const Tabs = TabNavigator(
{
Logs: {
screen: Logs,
// here I would like to recieve the jwt and pass it as a param to the logs screen
},
NewRide: {
screen: NewRide
}
},
{navigationOptions: ...}
}
export default tabs;
LoggedIn.js
export default class LoggedIn extends Component {
constructor(props) {
super(props);
}
render() {
return (
<View>
<Tabs jwt={this.props.jwt} /> // here I pass the jwt as a prop
</View>
);
}
What I am trying to do is pass a prop named jwt from my LoggedIn class located in LoggedIn.js to Tabs located in Router.js . From the Tabs call I would ultimately like to send the Jwt received as a prop to the Logs screen.
Im not sure how to to recieve the Jwt in the Router.js file and pass it to the logs screen. Any help regarding this would be hugely appriciated as i have been stuck on this for a good two days. Kind regards Matt.
You can pass a global parameter to the navigation which can be available in every screen for that navigation.
screenProps - Pass down extra options to child screens
Sample
const SomeTab = TabNavigator({
// config
});
<SomeTab
screenProps={/* this prop will get passed to the screen components as this.props.screenProps */}
/>

ExNavigator in react-native can't find Router

My routes were working fine with the built-in NavigatorIOS, but I wanted to add a custom font to the navigation so I decided to go with ExNavigator. I'm open to other component solutions, but first here is my problem:
From my initial route, the user is supposed to go to a detail view onPress. The initial route is loading, but the detail view is not working with ExNavigator.
I made an object for the router following exponent's docs. When the onPress event is triggered, I get an error: Can't find variable: Route
Here are some code snippets
app.js
class app extends React.Component {
render() {
return (
<ExNavigator
style={styles.container}
translucent={false}
initialRoute={
Router.getHomeRoute()
}/>
);
}
}
let router = {...}
export default Router;
main.js
<TouchableHighlight underlayColor={'#f3f3f2'}
onPress={()=>this.selectRow(row)}>
selectRow: function(row){
row = {row};
let route = Router.getDetailRoute(row);
this.props.navigator.push(route);
}
for detail.js i'm just including NavigatorIOS.
I get a react error if I try and put the router in any other file but app.js.