Blog

Simplified React Redux State Management

by | Jan 10, 2021 | 0 comments

ch4mp50ft@
CEO

Regardless your application is web or mobile, if you use react probably you may come across the topic of “state management”. If you have a clear idea of how redux manages state in the react app, it won’t be hard to manage your web or mobile app easily and properly. So let’s dive into it. To manage state in react with redux there are many packages available in the npm library that you can find.

The packages or number of packages you are gonna use will depend on your requirements and choices. For examples,

01. If you use google firebase.
With Firebase, you can use firebase and redux mixed libraries and make your backend development process simpler using firebase console.
These are some of the popular packages you may need,
react-redux-firebase, redux-firestore, redux-fire-auth, and apart from those there are many available in the npmjs library.

02. If you have the mindset to architect your application properly and scale over time.
When you are planning an app from scratch, you can think and rethink how you will maintain the app in the long term. In that time react-redux, redux-saga will be enough. But for additional logger purposes, you can use redux-logger and of course for the routing also you can find help from react-router-redux.


When it comes to the react apps, the main concern is UI components. There are two main types of UI components and are Container/Class and UI/Functional components.

And when calling API calls, we will grab some data from the backend and show it on user interfaces. Unlike basic HTML and javascript technologies (let’s take AJAX), react is very sensitive about browser DOM and therefore we can easily handle the DOM using DOM manipulation mechanisms. (using life cycle methods and hooks of react)

So where is the state?

Yes, the state is combined with the react components. What is the state? The state is something like a global store. The state is stored in a defined global store of react app.

Normally in the react apps, we can find two types of state values,

  1. State values that are initialized in the state object and updated inside the component. These values’ origin is global store.
  2. State values that are not in the global store but used inside individual components. These values don’t have many usages as those haven’t reusable requirements.
import React,{Component} from 'react';
class SampleClass extends Component {
  constructor(props){
    super(props);
    this.state={
      ownProp:'this is default text',
      inheritedProp:this.props.parentComponentProp
    };
  }
  render() {
    return <div>This is sample class component</div>;
  }
}
export default SampleClass

In the above example, ownProp’s value is initialized within the same class component while inheritedProp’s value is derived from the upper parent component or global store. If we consider how global store saving values with new example,

Your example app’s global state may look like this. When you logged in to the app authState looks like this and since you don’t have any items in the cart it will be an empty array.

{
  authState:{
    logged:true,
    username:'sashika'
  },
  cartState:{
    cartInfo:{
      items:[]
    }
  }
}

How authState’s has values and cartState hasn’t?

When you are managing state in the react app you have to initialize default values for state. Normally at the initialize time of the app authState has logged: false, userName: null at the very first time until someone tries to login with proper credentials. So you know why cartState looks like above.

Then how authState change to logged: true, userName:’sashika’? It happens through ACTION being called and the REDUCER set the auth state with login API call’s response.

According to this example, after you type credentials you will click on the login button. At that time we have to wire up action to call actual API call to invoke and grab data from the backend (server).

And reducer can be written to change certain values inside the global state object (global store). At that time you do not need to replace the whole state object, you can just update certain props of the state object by using the spread operator in javascript. If your data (logged: true in this example) is just one property of a state object, then you can just change that one prop of the state object (authState in this example ) without re-write or updating the entire state object.

How ACTIONS got the power to change UIs?

I mentioned actions do the call of API call in the above example. How does this actually work to change the UI of react app?

If we take the login event, when the user types the correct credentials and clicks on the login button it will call the function which is bind to that login button. That button onClick event is bound to the login action. To pass the API call and when retrieved the response, it may need parameters while calling actions before sending those to the state.

That API calling logic can be implemented inside the action. (Actions are very similar to the normal javascript function)

It’s good practice to separate actions based on their context. For example, authentication-related actions can be implemented in one JS file.
Now look at the sample auth action,

export const login=(credentials)=>{
  return function(dispatch)=>{
            axios({
              method: 'post',
              url: 'https://api.mydomain.com/login',
              data: {
                username: credentials.userName,
                password: 'credentials.password,
              }
            })
            .then((response) => {
                dispatch({type: "LOGIN_SUCCESS",  data:{logged: true, userName:response.data.username}})
            })
            .catch((err) => {
                dispatch({type: "LOGIN_ERROR", err})
            })
  }
};

 

Now data is ready to send for the state (dispatch) and to do that actions use the support of REDUCER. This means behind action invoke there is reducer and reducer does the actual state update. But keep in mind that actions are the frontline where interact with react components.

What is a Reducer?

A reducer is a place where the state (authState in the above example) changing actions are grouped (based on the context of state) and the direct point where real state change happens. For react app we normally introduce several states such as authState and cartState in this example. For example, all auth actions can wire up through the one reducer and we can call it authReducer. This reducer is also a JS file. Now check the sample auth reducer.

const initState={
    authError:null
};
const authReducer=(state=initState,action)=>{
    switch (action.type) {
        case 'LOGIN_SUCCESS':
            console.log('login success');
            return {
                ...state,
                logged : true,
                username : action.data.username
                authError: null
            };
        case 'LOGIN_ERROR':
            console.log('signup error');
            return {
                ...state,
                authError: action.err.message
            };
        default:
            return state;
    }
};
export default authReducer

 

In reducer normally we use switch statements to identify which action triggered and based on triggered action type update certain props of the state.

That is the roadmap of what happens behind the sense in react state managed app when you make an event in the react application. Since we’re managing our state of react app with the support of mentioned packages, we don’t have to worry about these state changes if we write logic properly. Once state updated our component will update according to the given logic in components.


For example, we can write logic to update navigation bar menu options to show the logout option once authState’s logged prop becomes true from the false. Wise versa we can remove updated navigation bar menu options once logged prop becomes false from true.

Sometimes when you’re giving logic to components those will become complex. Therefore make sure to break down the application components wisely. So you won’t be messed up with logic.

Now we’ll look at again how everything combined in the react app together using a sample diagram.

Also, please concern about the following areas when you’re using redux state management in your react app.

How to export multiple actions, reducers, components using index files and package.json files inside actions, reducers, component directories so your imports statements won’t give you a headache.

The best approach is to bind the state to the components.

This article was originally published to the medium by the same author.