Theme your Expo app with Redux and React Navigation

Recently whilst developing a React Native app (with Expo), I built a simple tab navigator using React Navigation library. I wanted to theme the app so that the header would change colour depending on which page you’re on. For example on the primary page it would be red and on the secondary page, when you change tabs, the header would become blue.

I ended up being able to do it using Redux. In this article, I will show you how you can theme your Expo app using Redux with React Navigation.

P.S. This article is written in British English however, the code is written using American English to make it more consistent (colour vs color).

React Navigation


Image for post
Image for post
Redux Store, from

The diagram above explains pretty well why you may need to use Redux. Passing state can be tricky in more complicated React Native apps, with lots of components and sub-components. Using redux we can change the state in one component and Redux will update the state in all the other components.

There are many great tutorials about Redux, I particularly liked this one. Here is brief summary how Redux will work with this app.

  • Redux sets the initial (state) colour to red
  • Change tabs from main to the secondary page
  • This dispatches an action to the Redux store (action is called toggleTheme)
  • The store then calls a reducer
  • The reducer (also called toggleTheme) updates the old state to a new state, it changes the colour from red to blue
  • Redux updates the state in all the components

Here is a GIF that might help clear up how it work.

Redux Flow, from
Redux Flow, from
Redux Flow, from


  • An Android emulator/device to test on
  • Install the following dependencies
"react-navigation": "^2.18.0",
"react-redux": "^5.1.1",
"redux": "^4.0.1",



├── src
│ ├── actions
│ ├── components
│ ├── containers
│ ├── reducers
│ ├── screens
│ ├── store
| └── themes
├── package.json
├── App.js


Image for post
Image for post

Here we define our two colours that will be used as themes, red and blue. I have given each colour a name because it makes the toggle logic easier to follow.


Image for post
Image for post

A reducer is a pure function which takes some state and returns a new state. In this example it gets passed the current theme colour and swaps it to the new theme colour.

In this example if the action is TOGGLE_THEME, we get the colour name from the payload and using a switch statement we swap the colours over. So if the current colour is red we update the state (colorData) to be blue.

Image for post
Image for post

Here we combine all of our reducers, in this example, we are only using the one reducer but if we had multiple reducers, The combineReducers function to would be necessary to combine them together. In this example we can simply add new reducers to the function as and when we need them.


Image for post
Image for post

This file defines all the actions we can dispatch to our store. In this example, we only need one action to toggle our theme.

Image for post
Image for post

In this file, we define our actions, so here we have a single action toggleTheme, which takes a theme as input and passes it as our payload, hence to access the name of the colour we use in our reducer.


Image for post
Image for post

The Redux store is used to store the current state for our app, we have to link our store with our reducers we can do this using the createStore function and import the reducers from reducers/index.js.


Image for post
Image for post

This acts as the main file for our app, to use Redux with our app we must wrap around Provider tags and set the store props to our store/index.js file. The <CustomTabNavigator> contains the logic for our two screens and the tab navigator.


Image for post
Image for post

Here is where we use react navigation to create our tab navigator. We define two screens called A and B, each screen has a different tab colour, red for A and blue for B. The main part of this file is the following

tabBarOnPress: ({ defaultHandler }) => {

On tab change (from A -> B), we detect the tab press and dispatch the toggleTheme action to the Redux store. So when we change tabs from A -> B the colour in the store will change from Red -> Blue and vice versa for B -> A.

One other thing to note is the tab colour is set using the following function. The colour is passed by the tabBarOptions.

const commonTabOptions = color => ({
activeTintColor: 'white',
pressColor: '#fff',
inactiveTintColor: '#ddd',
style: {
backgroundColor: color,
tabBarOptions: commonTabOptions(
Image for post
Image for post

This file does most of the heavy lifting for this app, this is where most of the logic sits. So, first of all, we have a button, which calls toggleTheme on a press of the and passes the current colour (state) as an argument.

title="Toggle Color"
onPress={() => this.props.toggleTheme(this.props.color)}

The colour of the button is also using the current (state) colour, so in this case, it will start off as red, this.props.color. We can access the current state using this.props.

const mapStateToProps = state => ({
color: state.Theme.colorData,

This function is used to map the Redux store to the state of this component. We map state.Theme.colorData, where Theme is the name of our reducer and colorData is the item name. In this example, we've mapped the current colorData to color props in this component.

const mapDispatchToProps = dispatch => ({
toggleTheme: color => dispatch(toggleTheme(color)),

This function maps a function to an action (and dispatches it), in this example when the toggleTheme function is called in the component it will dispatch the toggleTheme action to redux. So when the button is pressed it will dispatch an action to toggle the theme.


Image for post
Image for post

This is an example of one of our screens, it’s very simple just the page name and <ToggleTheme> component.


Image for post
Image for post
The app running on an Android emulator.

Here is an example of the app running, as you can see there are two ways we can toggle the theme. We could use the button click, or change tabs.

Extra Task: If you want some practice, currently this won’t detect a swipe action to change tabs look at how you can do this. An example of it working can be found here.

Written by

Software Engineer | Pythonista | Typescripter | Docker Advocate |

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store