React Native: State Management with redux and redux-thunk

Divyaswor Makai
5 min readMar 7, 2021

If you are one of those who are learning or working with React for web application development or React Native for hybrid mobile application development, then you might have crossed path with the term state management. In this article, I will present my understanding of state management and how to manage the state in a React Native app using redux.

What is State Management?
Starting off with the definition. The application that we develop use various levels of states that might be limited to a component, page or the entire application. For those who have just started with the React world, the first thing their mind might come across could be declaring states in the main index file and then passing it as props to the children. This is a solution but not the ideal one. Using state management tools with big community would be the best way to go. Redux in case of the React environment.

Getting started with React Native Project

As for the background information on React Native, it is a framework for building native apps using React. If you don’t know how to get started with React Native follow the docs here. When you initialize a new project, you might see the following folder structure.

Going through all the files might take some time. So I’ll be discussing them in short.

  1. android/ios: These folders are responsible for the android and ios build of the application.
  2. package.json: It holds data for the packages that have been used and the scripts that can be used along with the details related to the project.
  3. index.js: Index file is the entry point of the application where the main activity is registered.
  4. App.js: This is the main activity from where child components and such are placed.
  5. babel.config.js: JS config file for Babel(JS transcompiler)
  6. eslintrc.js: Contains rules for static code analysis
  7. metro.config.js: Contains rules for metro which is a JS bundler.

Installing Redux and Redux-thunk

We will be installing 3 packages:

npm install --save redux react-redux redux-thunk

New term introduced here is redux-thunk. It is a middleware to redux that is used primarily used for asynchronous data handling in redux. You can learn more about it here.

Let us start by creating a few files and a directory to store our reducers. To understand what is reducer and the lifecycle of redux you can follow the official documentation.

Here I declared a reducers directory where we will be storing our reducers and a store.js file where we will use the reducers to define the states and such.

// store.jsimport { applyMiddleware, combineReducers, createStore } from 'redux';import thunk from 'redux-thunk';
import testReducer from '../reducers/testReducer';
const reducer = combineReducers({
test: testReducer,
// declare other reducers here, // the key name here will be used to select the value from state
});
const store = createStore(reducer, applyMiddleware(thunk));
export default store;

Here, combineReducer is esssential in case of other reducers. The names that are used as key in the reducer is essential when we need to select them using the useSelector. We use redux-thunk as the middleware in the store. As for the testReducer in the reducers directory

// testReducer.jsconst testReducer = (state = [], action) => { 
switch (action.type) {
case 'UPDATE_TEST': {
return action.data;
}
case 'RESET_TEST':{
return '';
}
default:
return state;
}
};
export const updateTestData = (data) => {
return (dispatch) => {
dispatch({
type: 'UPDATE_TEST',
data: data,
});
};
};
export const resetTestData = () => {
return (dispatch) => {
dispatch({
type: 'RESET_TEST',
});
};
};
export default testReducer;

Here, we have defined a testReducer that takes initial state as an empty array and takes in action, the action has type for which action is carried out and data that we want to update with. Two functions have been defined to dispatch and change the data in the state. This feature is enabled by redux-thunk, else we would have to call dispatch from where we want to change the state from. updateTestData takes in a data whereas resetTetsData doesn’t take any, their dispatched effect have been described in the testReducer defined above them. After this we will modify the App.js to use the store that we have defined.

App.jsimport React from 'react';
import { Provider } from 'react-redux';
import Child1 from './components/Child1';
import Child2 from './components/Child2';
import store from './store';const App = () => {
return (
<Provider store={store}>
<Child1 />
<Child2 />
</Provider>
);
};
export default App;

We have created two components to showcase how redux handles global states.

// Child1.jsimport React from 'react';
import { Button, Text, View } from 'react-native';
import { useDispatch, useSelector } from 'react-redux';
import { updateTestData } from '../reducers/testReducer';const Child1 = () => {
const test = useSelector((state) => state.test);
const dispatch = useDispatch();

return (
<View>
<Text>This is Child 1</Text>
<Text>Test Data: {test.testData}</Text>
<Button
onPress={() =>
dispatch(updateTestData({ testData: (Math.random() * 1000).toString() }),)}
title="Update Test Data"
/>
</View>
);
};
export default Child1;

Child 2 component goes like this.

//Child2.jsimport React from 'react';
import { Button, Text, View } from 'react-native';
import { useDispatch, useSelector } from 'react-redux';
import { resetTestData } from '../reducers/testReducer';const Child2 = () => {
const test = useSelector((state) => state.test);
const dispatch = useDispatch();

return (
<View>
<Text>This is Child 2</Text>
<Text>Test Data: {test.testData}</Text>
<Button onPress={() => dispatch(resetTestData())} title="Reset Data" />
</View>
);
};
export default Child2;

That is all the things we need to do for now. There are no styling done whatsoever as this is a demo only. If you go through the code once, you can easily understand what have been done in the child components.

In Child1 component, we have a declared a button that calls upon the updateTestData function that was defined in the reducer earlier, we send random data for now. In Child2 component, we declared another button that will reset the data. The result should loook something like this.

So here you have it, a complete guide to using Redux with React Native. For React lovers, this might be a piece of cake as it is same as implementing it with a web application for others let it be a guide.

Thanks for reading.

--

--

Divyaswor Makai

Full Stack Web Developer, Game Developer, ReactJS, VueJs, NodeJS, ExpressJS, Unity, React Native.