State Management With Redux — React Native

Abdullah Liaqat
The Startup
Published in
4 min readJul 16, 2020
React Native + Redux

Why Need State Management in React Native App?

One might wonder why global state management is required in a React Native application? Before answering this question, let us analyze the problem. The React Native technology is based upon the React Component Tree. A component gets the data from its parent component in the form of “props” and can hold its local “state”. The props can only be trickled down from the parent to the child and there is no convenient way to pass the data from the child to the parent component.

So, here comes the role of redux. It enables us to have global state management normally called a redux store which is accessible to all components without having the hassle of passing data as props. But obviously props are there for a reason and can be helpful in a lot of scenarios.

Getting Started with Redux in React Native

Let’s get started with a simple example of a counter based on Redux. We need to install a few packages in our project. We need redux and react-redux for now. We will look into redux-thunk middleware in a more complex example next time.

// Using npm
npm install redux react-redux
// Using yarn
yarn add redux react-redux

Redux works with the help of three main components:
1. Store
2. Reducers
3. Actions

So let’s create a redux folder in our project and add some files. The structure will be as following:

Redux Folder in the Project
// store.jsimport { createStore} from "redux";import counter_reducer from "./reducers/counter_reducer";const store = createStore(
counter_reducer
);
export {store};

In store.js, we have created a redux store which is a function that takes a reducer, counter_reducer in our case, as a parameter.

// reducers/counter_reducer.jsconst initialState = {
counter : 0
};
const counter_reducer = (state = initialState, action) => {
switch(action.type){
case "increment": {
return {...state,counter:state.counter + 1};
}
case "decrement": {
return {...state,counter:state.counter - 1};
}
default: {
return state;
}
}
}
export default counter_reducer;

counter_reducer is the main action handler of our store and updates the state of the store according to the action dispatched in the application.

// actions/counter_actions.jsconst increment_counter = () => {
return {
type: "increment"
}
}
const decrement_counter = () => {
return {
type: "decrement"
}
}
export {increment_counter, decrement_counter};

Last but not the least, our pre-defined actions that return the type of action dispatched to the reducer.

Redux may seem hard to understand at first but once you get familiarized with the flow, everything is pretty straightforward.

Consuming Redux Store in the App

Now, let’s connect the redux store to our application. First of all, we need to give access of the store to our root component.

// App.jsimport { Provider } from "react-redux";
import {store} from './redux/store';
...
const App = () => {
return(
<Provider store={store} >
<MainApp/>
</Provider>
)
}
...

Provider from react-redux will act as a wrapper to our root component.

// MainApp.jsimport React from 'react';
import {View, Text, Button} from 'react-native';
import {useSelector, useDispatch} from 'react-redux';
import {
increment_counter,
decrement_counter
} from '../redux/actions/counter_actions';
const MainApp = () => {
const counter = useSelector(state=>state.counter);
const dispatch = useDispatch();
return(
<View
style={{
flex:1,
alignItems:"center",
justifyContent:"center"
}}
>
<Button
title="increase"
onPress={()=>dispatch(increment_counter())}
/>
<Text>{counter}</Text>
<Button
title="decrease"
onPress={()=>dispatch(decrement_counter())}
/>
</View>
)
}
export default MainApp;

We can access the Redux Store using useSelector() hook. The component will rerender on observing any change in the store. So, we always get the updated value from the store. The useDispatch() hook is used to dispatch the actions to the reducer of the store.

Now let’s see the App in action.

Summary

The setup for the Redux Store in a React Native application takes these steps:
1. Creating a reducer with an initial state.
2. Creating a store with Reducer defined in the previous step.
3. Defining actions for Reducer.
4. Wrap the Root App Component within Provider from Redux Store.
5. Access store state in any component using useSelector() hook.
6. Dispatch any action to Reducer using useDispatch() hook.

You can find the code for this example following the link below:

https://github.com/Abdullahliaqat9010/redux-counter-example

--

--