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