Using React-Native (0.19) and Redux, I'm able to navigate from scene to scene in React Components like so:
this.props.navigator.push({
title: "Registrations",
component: RegistrationContainer
});
Additionally I'd like to be able push components to the navigator from anywhere in the app (reducers and/or actions).
Example Flow:
Problems I'm seeing with my approach:
navigator
into any action that needs it. I feel like I'm missing something slightly simple on how to access Navigator from actions without sending in as a parameter.
To handle your app's navigation state in Redux, you can pass your own navigation prop to a navigator. Once you pass your own navigation prop to the navigator, the default navigation prop gets destroyed. You must construct your own navigation prop with state , dispatch , and addListener properties.
In my opinion the best way to handle the navigation with Redux is with react-native-router-flux, because it can delegate all the navigation logic to Redux:
You can change the route from the reducer;
You can connect the router to the store and dispatch its own actions that will inform the store about route changes (BEFORE_ROUTE
, AFTER_ROUTE
, AFTER_POP
, BEFORE_POP
, AFTER_DISMISS
, BEFORE_DISMISS
);
Here is an example on how easily you can save the currently focused route in the store and handle it in a component (that will be aware of being focused):
1. Connect a <Route>
to Redux
Connecting a <Route>
to Redux is easy, instead of:
<Route name="register" component={RegisterScreen} title="Register" />
you might write:
<Route name="register" component={connect(selectFnForRegister)(RegisterScreen)} title="Register" />
You can also simply connect the component itself in its own file like you usually do.
2. Connect a <Router>
to Redux
If you need to inform Redux of the navigation status (i.e. when you pop a route) just override the <Router>
component included in react-native-router-flux
with a connected one:
import ReactNativeRouter, { Actions, Router } from 'react-native-router-flux'
const Router = connect()(ReactNativeRouter.Router)
Now when you use a <Router>
it will be connected to the store and will trigger the following actions:
Actions.BEFORE_ROUTE
Actions.AFTER_ROUTE
Actions.AFTER_POP
Actions.BEFORE_POP
Actions.AFTER_DISMISS
Actions.BEFORE_DISMISS
Take a look at this for an example.
3. Catch the interested actions in your reducer
For this example I have a global
reducer (where I keep the information needed by all my app) where I set the currentRoute
:
case Actions.AFTER_ROUTE:
case Actions.AFTER_POP:
return state.set('currentRoute', action.name)
Now the reducer will catch every route change and update global.currentRoute
with the currently focused route.
You also can do many other interesting things from here, like saving an history of the navigation itself in an array!
4. Update your component on focus
I'm doing it on componentDidUpdate
of my component of the route named payment
.
If global.currentRoute
is payment
and the previous global.currentRoute
was different, than the component has just been focused.
componentDidUpdate(prevProps) {
const prevRoute = prevProps.global.currentRoute
const currentRoute = this.props.global.currentRoute
if (currentRoute === 'payment' && prevRoute !== currentRoute) {
this.props.actions.doSomething()
}
}
P.S.: Remember to check currentRoute === 'payment'
, otherwise you'll start doSomething() on every route change!
Also, take a look a the README.md for learning other stuff about the integration with Redux.
Hope it helps, long live Redux!
Maybe you could pass the information about title and component in an action and the component with the navigator can then push the right scene with the information of the state.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With