In this blog post I will demonstrate how to connect React Navigators to Redux Stores. But first, let's quickly understand what react navigators are and why would we want to connect them to redux stores anyway.
React Native doesn't have a built-in API for navigation like a web browser does which is where React Navigation library comes into picture. React Navigation comes with a built-in set of navigators, such as, StackNavigator, TabNavigator and DrawerNavigator to allow you to define your application's navigation structure. The library however also provides APIs to build custom navigators, as well. Besides, navigators also render common elements such as headers and tab bars which are configurable via navigationOptions
static property which is either an object or a function that returns an object containing various configuration options.
Now assume you already have a navigator defined in your application. But you also need to perform some side-effect which could be a function of the navigation action itself and a change in an application state defined in your Redux Store. This is where you may want to connect your react navigators to your redux stores. Another such use case could be to have your navigator configuration based out of changes in an application state. For example, displaying badges on the tab bar icons on reception of push notifications.
Let me elaborate on a use case via which I would attempt to illustrate the connection between navigators and stores.
While working on a personal app I stumbled upon this requirement where I wanted to show badges on the tab bar icon upon reception of push notifications and hide them when switched tabs. This as you might have already guessed was driven via a redux state called pushNotificationSeen
. Let me explain.
What I implemented is a BottomTabNavigator made out of two StackNavigators and five react components as screens.
The tab bar icon representing the intimationsFlow
navigator needs to show a badge reflecting the reception of a push notification when the screen is not in focus i.e., only in the cases when other tabs are in focus. However, as soon as the intimationsFlow
navigator tab is in focus, we need to hide the badge, indicating that the notification has already been read. Here, the reception of a push notification is recorded as an application state called pushNotificationSeen
( set to false
) which is supposed to be updated ( set to true
) as part of the side-effect in the navigator i.e., when the notification is read, as explained above. This evidently requires a connection between the navigator and the store so as to make pushNotificationSeen
state available in the navigator.
Note that the createStackNavigator
API returns a navigator that itself is a component like any other react components which could be connected to the redux store using the connect API from the react-redux library and all. But for us to be able to respond to changes in the pushNotificationSeen
state and perform side-effects from within the navigator, we would need to extend the behaviour of our existing intimationsFlow
navigator by creating a custom navigator.
connect navigator to store
line:67-71: The state pushNotificationSeen
is made available to the IntimationsFlowNavigator
component by connecting the navigator to the store with the help of the connect()
API from the react-redux
library.
respond to changes in state
line:51-55: The navigator react component is re-rendered for every change in the pushNotificationSeen
state. As part of the componentDidUpdate()
life cycle method, we make sure of supplying the new pushNotificationSeen
state value to the navigationOptions
navigator property. This is required because navigationOptions
is a static property and can't access the props
directly.
render badges
line:28-46: Conditional rendering is performed in order to show/hide badge on the tab bar icons. Notice that it's a function of both the navigation action and the redux state.
perform side-effects
line:60-63: One must also note that navigationOptions
is not the right place to perform any sort of side-effects. In order to perform any side-effect in response to navigation events we make use of a special component called NavigationEvents.
Finally, we compose our tab navigator with our custom navigator, like so:
Hope this post give you a fair idea on why and how to connect your navigators to your stores.