React-redux – react bindings; react-native-router-flux – for navigating between screens. Redux-thunk – middleware allows you to write action creators that return a function instead of an action. Immutability-helper – Mutate a copy of data without changing the original source. Redux-logger – logs r edux actions + state in your browser.
Looking for Books?
React Native
The Complete React Native and Redux Course
React Native: Advanced Concepts
Build React Native Apps for Android and iOS
React Native for Absolute Beginners
Getting Started with React Native
React and Redux
Modern React with Redux
React JS and Redux - Mastering Web Apps
Advanced React and Redux
React 16 - The Complete Guide (incl. React Router 4 & Redux)
React Fullstack
Beginner Full Stack Web Development: HTML, CSS, React & Node
The Full JavaScript & ES6 Tutorial - (including ES7 & React)
Node with React: Fullstack Web Development
GraphQL with React: The Complete Developers Guide
This article is about integrating react native with redux in a way that I find easy to set up and work with. It is based on what I have learnt from scaling up React applications. Click here to view the source code.
Redux is a predictable state container for JavaScript apps. It is an awesome tool for handling your application’s state. If you google react native and redux set up you will find that a lot of people have different was setting up their projects. I am more comfortable with the fractal folder structure approach .
Okay, let’s start by creating our a simple react-native application. I am using a mac but you can still follow through on windows. If you haven’t set up your development environment, please checkout the getting started guide on react native’s official website.
1. Create a new application.
Open your terminal and use the React Native command line interface to generate a new React Native project called “ReactNativeRedux”:
react-native init ReactNativeRedux
Run your application from within the “ReactNativeRedux” folder. Use “react-native run-ios” for iOS and “react-native run-android” for android.
cd ReactNativeRedux
react-native run-ios
You should get something like this:
2. Install Dependencies
Now we need to install the following npm packages.
- redux – to manage the state of the app.
- react-redux – react bindings
- react-native-router-flux – for navigating between screens.
- redux-thunk – middleware allows you to write action creators that return a function instead of an action.
- immutability-helper – Mutate a copy of data without changing the original source.
- redux-logger – logs redux actions + state in your browser.
Let us first install three packages by running the following commands in our terminal.
npm install redux react-redux redux-thunk react-native-router-flux immutability-helper –save
After that we can go ahead and install redux-logger as a dev dependency buy running the following command..
npm install redux-logger –save-dev
3. Project Structure
I am going to use a Fractal folder structure you can read more about it from David Zukowski’s github wiki. Our project will look something like this:
Create the src directory in the root of your project folders you should end up with something like this:
In the root folder delete “App.js” which was auto generated for us by react-native-cli.
4. Setting Up the project with Redux
Now that we have our folder structure in place, we can go ahead and start coding. Let’s start by opening index.js in project’s root and replace its content with the following:
./index.js
AppRegistry is the JS entry point to running all React Native apps. Our app will be bootstrapped and rendered from “./src/main.js”.
./src/main.js
We still need to create the store and the AppContainer component. The store will be passed to the AppContainer as props for use with react-redux
Provider
../src/store/createStore.js
In this file we write a function that creates our store. Our
initialState
object is empty but you can use it to set your applications initial state. Under middleware configuration we create our middleware array. As stated earlier, middleware allows you to write action creators that return a function instead of an action. We are then conditionally pushing the logger to the middleware because it is only used during development../src/AppContainer/index.js
AppContainer is just a react component. The most important thing here is we passing the store to the
Provider
which is a lightweight dependency injection mechanism. Your components can now make use / access the redux store easily. In this file we are also importing the “Home” component from “HomeContainer” which we are going to create soon.react-native-router-flux
is a routing package that allows you to:- Define scene transitions in one central location
- Without having to pass navigator objects around, and allow you to
- Call transitions anywhere in your code with a simple syntax (e.g.
Actions.login({username, password})
orActions.profile({profile})
or evenActions.profile(123)
– all params will be part ofthis.props
for given Scene component).
The syntax for creating routes can be seen above. The scenes aka routes act as separate views.
./src/routes/Home/components/Home.js
Previously we created a few folders in the routes directory. Let’s see how we can make use of them starting with the react “Home” component. The components folder is where all our react components specific to the Home route will reside. Each route will have a main container component where we can import the rest of the components specific to this route.
In this route we have a prop called name
<Text>Hello {this.props.name}</Text>
which we are going to change when a button is clicked. We are going to wire up everything soon../src/routes/components/HomeStyles.js
Styling for this component will be written in “HomeStyles.js”, so make sure you create this file in the same folder as the “Home.js” component.
/src/routes/module/actionConstants.js
In this file we simply create an object with our action constants which we then import in “./src/routes/module/index.js”
./src/routes/module/index.js
This is were we keep our collection of reducers, constants and actions. First we import
update
to help us mutate a copy of the state without affecting the original source. We then import the constants object from “actionConstants.js”.The function
changeName
will be called when a button is clicked. The function dispatches an action called CHANGE_NAME
with a payload to mutate the sate. The initialState
in this case is a name “John”. We will use redux to change the name to something else when the button is clicked.Next we need to create an action handler to mutate the name state. The action handle uses
update
imported from immutability-helper
which helps us change the name’s state without changing its original source../src/routes/store/reducers.js
In file we combine all the reducers from our app into one single “root reducer” which is the passed to the store. We split reducers to reduce complexity as the app grows. I this file we only have one reducer imported from the Home route module folder.
./src/routes/container/HomeContainer.js
Previously in “./src/AppContainer/index.js” we “provided” our redux store to our application, now we can go ahead and connect our components to it. There is no direct way for react to interact with the store. Data can only be retrieved by obtaining current state or dispatching an action to alter the state.
connect
does the “connecting” for us as seen below.With all that set up lets run our app and see react-native + redux in action.
cd ReactNativeRedux
react-native run-ios
Clicking on the button should change the name. To view the original source code please click here.