How to structure your React Native application using Redux?
I have worked on production React Native Redux application for the past 5 months, which was supposed to only take 3 month when we first analyzed. We later concluded that this 50% increase was due to poorly structured application which caused a lot of refactoring and duplicated codes. If you are planning to use redux in your react-native application, please read on.
I will assume you have basic knowledge about React Native and Redux, so if you are new to Redux, you can check out my previous post on Redux and come back to this post.
What is React Native?
I would assume you already know the basics about React/React Native, if not please check out the official guide.
What is Redux?
In short, it is both a design pattern and a library. Redux and React-Redux is a small library that helps you follow this design pattern through some restrictions and let you write less boilerplate code. These two libraries are essential when developing React Native application using Redux.
Terminology
I want to list some terminologies and explain what they are here, so you can refer back to here whenever you are lost.
- React Component — A JavaScript class that extends React.Component. Can also be created using React.createClass().
- Stateless Functional Component — A JavaScript function that accepts props as parameter and returns React Component. This can be used instead of normal React Component. Also referred to as Pure Component, Dumb Component, available in React>= 0.14. In redux stateless components are often stated as Presentational Component.
- Higher Order Component (HOC)— A JavaScript function that accepts React Component as a parameter and returns a new React Component.
- Container Component — HOC returned from connect(). It connects your presentational component with redux store.
- Redux Store — Immutable JavaScript Object that store the state of your entire application. Note that there is only one store for the entire application.
- Middleware — A function that accepts store as parameter and returns dispatch function that accepts action as its parameter. This returned dispatch function will then override the existing store dispatch function.
Maximizing Code Reuse
I will be using react, react-native, react-native-router-flux, redux, react-redux. I will also use 3 most popular redux middlewares for the completeness.
components/Login/actions.js: Implements Action creators for login page.
components/Login/index.js: Imports one or more selectors, actions.js, and Login.js in order to connect them up.
components/Login/Login.js: Presentational component of login page.
reducers/loginReducer.js: Implementation of reducer and selector for login page.
reducers/navReducer.js: Implementation of reducer and selector for navigation.
reducers/rootReducer.js: Imports all other reducers and combine them. Implements higher order selectors for all other selectors.
store/configureStore.js: Imports rootReducer, and all of the middlewares, and use them to create a store.
actionTypes.js: Implements all action types used by reducers and action creators.
App.js: Connects react-native-router-flux’s Router to redux store. Import configureStore.js in-order to create a new store. Implement all of the Scenes declaratively.
Here is all of the code for those files and brief explanation on why I structured it this way.
Here is a link to bitbucket for all of the code above.
https://bitbucket.org/bosung90/rnrf-redux-starterkit/overview
Hopefully with this way of structuring your application you can increase the code re-usability, separation of concerns as much as possible. I know I won’t be making the same mistake again.