For enquiries call:

Phone

+1-469-442-0620

April flash sale-mobile

HomeBlogWeb DevelopmentWhat is React Redux?

What is React Redux?

Published
05th Sep, 2023
Views
view count loader
Read it in
25 Mins
In this article
    What is React Redux?

    React is a JavaScript library for building user interfaces. One of the most popular UI libraries in use today, React is opensource and is maintained by Facebook. React has the best community support, with millions of developers who take part in discussions on best practices, React architecture, and the way forward with React.

    You can read more about React here.

    In this blog you are going to learn about React Redux. We can use it along with React for state management within the application.

    Prerequisites:

    • This blog expects you to have good knowledge of JavaScript.
    • You should have basic understanding of React, React Hooks and Components in React.
    • Please ensure that the latest versions of npm and node are installed in your machine.

    To get started with React Redux, let’s first see what Redux is:

    What is Redux?

    Redux is a predictable state container for JavaScript apps, which means that Redux is predictable and it stores the state of your application. Redux will store and manage the application state.

    Redux itself is a standalone library that can be used with any UI layer or framework. Along with React, Redux can be used with many other JavaScript libraries and frameworks such as Angular, Vue and even with Vanilla JavaScript.

    You can read more about Redux here.

    When we are building a large-scale application, there is a need for a state management tool to avoid prop drilling all through the component. Redux is the most popular and widely used state management tool today.

    Note: Redux does what context api does in React. However, Redux was introduced before context api was introduced, and it continues to be the most popular state management library.

    In the next part of this article, you will learn to use Redux and in later parts you can learn how to integrate it with your React application.

    Learn Redux:

    Here you will understand the essential core concepts of Redux before learning how to use it with React.

    Start with creating an empty folder with the name Redux-Learnings in your desired location and open the folder in your favourite editor. VScode is preferred.

    Initially your project folder looks like this when it is opened in VScode:

    It should be empty. Let’s setup our project first.

    Now, let’s initialize a package.json file to store all our dependencies to learn Redux.

    Open integrated terminal for vscode and navigate to the project location.

    Next, run the below command in our terminal to initialize package.json in our project.

    Command: npm init –yes

    There should be a package.json file inside the project as shown below.

    The next step is to install redux as a dependency for our project. Run the below command in the terminal to add redux as a dependency.

    Command: npm install redux

    If you check package.json file, you can see redux listed under the dependencies as shown below:

    Now create a file with the name index.js at the root level of the project and add a simple console statement to see the output on the terminal as shown below.

    Now, run the below command to run the index.js file.

    Command: node index

    It has to print the console statement to the terminal as shown below.

    Let’s start learning some theory behind Redux.

    Redux has 3 main components:

    1. Store
    2. Action  
    3. Reducer

    We will explain these components with the help of a real-world scenario.

    Imagine there is a restaurant, and you want to buy a meal. You will go to the restaurant and tell the retailer that you want to BUY a meal. The retailer takes out the meal from the bunch of meals with him, and gives it to you. You will then pay the money for the meal and get the receipt for the purchase. The receipt for the purchase is the proof that the number of meals has been decreased by one.

    Let’s see the 3 components in relation to the above scenario:

    1. Store: The store holds all the states of the application. This is similar to the restaurant holding all the meals.  
    2. Action: The Action here is to BUY_A_MEAL which describes what has happened. In this case you have bought a meal. The action describes changes in the state of the application.  
    3. Reducer: Reducers are similar to the retailer. They connect the store to the actions. In this case the retailer is decreasing the number of meals the restaurant (store) has. Reducers update the store according to the action.

    To put the 3 components of Redux into code, it’s important to learn the 3 main principles of Redux:

    1. The state of the whole application is stored in a single main object in the store. This means state is a single JavaScript object and lies inside the store. In our example, all the meals of the restaurant are to be represented in a single object. For example: { numberOfMeals: 10}
    2. The only way to change the state is to emit an Action. Emitting an action is the way of letting the Redux know what has happened. It’s an object describing what has happened. In our example BUY_A_MEAL is the action which is describing the action of buying a meal. You are NOT ALLOWED to update the state directly, but you always need an action to update the state.  
      Actions have types. For example: {type: “BUY_A_MEAL”}
    3. To specify how state changes based on actions, we use Reducers. A Reducer is a function that take initial state and action as inputs, and returns new state based on the type the action has. An example of a reducer for the above example is shown below. It decreases the number of meals in the restaurant (store).
    const reducer = (state, action) => {
      switch(action.type) {
        case BUY_A_MEAL: 
          return {
            numberOfMeals: state.numberOfMeals-1
          }
      }
    }

    Now let’s start coding our Redux app.

    As you have seen already, the 3 main components of redux are to be implemented in code. Let’s start with Actions.

    Creating Action:
    As you know that Actions are plain JavaScript objects and have ‘type’ property, which indicates the type of the actions being performed. You are not restricted to just having a type property;  instead, you can have additional properties as well.

    Also, in Redux we have action creator. As the name suggests, an action creator is a function which simply creates an action.

    Let’s go back to the project we have setup earlier and start coding Actions.  

    The Action Type and the Action Creator for our restaurant example can be written as shown below.

    Here BUY_A_MEAL is an action type and function buyMeal is an action creator, which returns an action which has type and the description in it.

    Creating Reducer:

    As we already know, a reducer is a function which takes in initial State and action, and returns a new state based on the type of action.

    The reducer can be created as shown below:

    Here the reducer is taking in the initial state and the action and returns the new state in the switch statement, where we compare the type in the case block and return the new state object.

    …state means that we are creating a copy of the state object and we are changing only the required properties.

    However, it's important to keep in mind that in redux we cannot change the state. Instead a new state is created with the changed properties and that is stored inside the Store.

    Creating Store:

    Before creating a store, its required to know the characteristics of Store:  

    • Store holds the state of the application. 
    • Store provides a method called dispatch which allows updates to the application state. Dispatch method accepts an action as its parameter. 
    • Store allows components to access the state via getState() method. 
    • Registers listeners via subscribe method. That is the listener is called whenever the state is changed inside the store. Listener is a function which is passed to the subscribe method to call whenever the state changes. 
    • Unregister the listeners using the function returned by the subscribe method.

    Now let’s implement all the above in the code. 

    If you see, we already have the state object by the name initialState in our code. Let’s create a store to hold our state using the redux package we installed earlier.

    As shown above, import Redux package using the required syntax. We need to make use of createStore method in Redux to create a store.

    Create a store by calling createStore method we pulled out from redux.

    createStore takes reducer as the parameter which has the application state.

    The store we created has the getState method which gives us the state of the application. To prove this, let’s add the console statement as shown below.

    If you run the file using node index command, you can see the console statement is printing the initial state to the console.  

    Now let’s quickly implement subscribe and dispatch methods as shown below.

    As mentioned earlier subscribe method takes a function as an argument. Here it’s a simple console statement which prints the state.  

    dispatch method takes in the action creator as an argument. I have just called it more times to trigger the state transitions more times.

    If you run the index file, you can see that the subscribe method is calling the listener function for every state change, and printing the new state as you can see above.  

    Now let’s unsubscribe to the listeners by calling the method returned by the subscribe method as shown below.

    Capture the unsubscribe method returned by the subscribe method, and call it in the middle to prove that we are unsubscribed to the state changes.

    If you can see above, listener has been called only 3 times for the 4 dispatch calls we made, as we unsubscribed before the 4th dispatch call.

    What is happening when we call dispatch method?

    When we call the dispatch method it dispatches an action buyMeal to the reducer which is returning the action which has a type BUY_A_MEAL. Now the reducer looks at the action type and compares with the case mentioned and returns the new state. As the state changes and the new state gets created in the store, the listener gets called and prints the new state to the console.

    This is the flow of redux. Going forward, do make sure that you understand and remember this flow.

    What if we have multiple actions?

    Let’s take the restaurant example again and say that we have snacks along with meals and we have different retailers(reducers) for each of these.  

    So, first step first, you need to update the initialState object to add the number of snacks and action type to buy a snack as shown below.

    Now let’s add an action creator to buy a snack (buySnack method).

    And also, a reducer case to handle buying a snack case

    And also add some dispatch methods to dispatch buySnack action.

    Now if you run the index.js file and see the terminal output when buyMeal is dispatched, only the number of meals decreases, and when buySnack is dispatched only the number of snacks decreases.

    This method of using a single reducer works in this case. However, in a large-scale application, it gets hard to maintain and debug, also hard to keep track of the work flow.

    So, in many cases developers tend to create multiple reducers.  

    Create multiple reducers:

    For this you need to split the initial state of the application within index.js as shown below

    Here, initialState object has been split into 2 state objects; one to store the number of Meals(initialMealState) and one to store the number of Snacks(initialSnackState).

    Similarly, we will split the reducer into 2 parts.

    Reducer related to Meals.

    Here, we have made mealReducer to handle actions related to Meals.

    Reducer related to Snacks.

    Here, we have made snackReducer to handle actions related to Snacks.

    If you observe by splitting the state and reducer, we are maintaining the centralized state and reducer functions for each component or feature in our application. By doing this it's always easy to maintain the code and to keep track of the workflow too.

    But if you look at the createStore method there is reducer passed in as an argument but now it no more exists. So, we need to combine the reducers before we pass it to createStore method.

    Combining Reducers:

    Combining reducers is very simple, and we can do this by using the combine reducers function which redux package offers.

    Extract combineReducers function from redux package as shown below:

    Now we need to combine all the reducers we have using the method we extracted above.

    The combineReducers function takes an object as a parameter which has all the reducers we have created as a key value pairs, and its generally called as rootReducer.

    We have to pass that rootReducer as an argument to the createStore method as shown in the above image.  

    Now if you run the file using node index you will see something like this inside the terminal.

    The meal and snack in the state object corresponds to the meal and snack keys we specified while combining the reducers.

    Now we have centralized state and reducers for each of our meals and snacks. We can add more actions to the existing reducers or even add new reducers. Also, it’s easy to maintain the code.

    This is the flow of the redux. We dispatch an action which has a type property to the reducer, and the reducer—based on the action type— updates the store accordingly.

    In real time applications, the actions are not synchronous as we have learnt above. We may have asynchronous actions, or we may want to add additional functionality to our redux workflow. For all of this we need to use middlewares.

    Middlewares:  

    Middlewares are the suggested way to extend redux functionality. Middlewares provide third party extension between dispatching an action and the moment the action reaches the reducer.

    Middlewares are normally used for logging, crash reporting or to perform some async tasks.  

    For example, we will now see how to add a middleware by using redux-logger middleware.  

    Read more about redux logger here.

    To install redux logger, go to vs code and run the following command in the terminal.

    Command: npm install redux-logger

    Now if you go to the above-mentioned link for redux logger, you will find the code we write now.  

    We need to require the redux logger we just installed and create a logger as shown below.

    Now to apply this middleware, Redux has a function built into it which is called applyMiddleware.

    Extract applyMiddleware function from redux as shown below.

    Now pass the applyMiddleware as a second parameter to the createStore function as shown below.

    applyMiddleWare takes all the middlewares we have as arguments. In our case, it is logger.

    To see the middleware in action, remove the console.log statement inside the subscribe method of store and run the file using node index. You should see the outputs of the logger in the terminal as shown below.

    As mentioned above the actions used in the above example are synchronous actions but in real time applications the actions will be asynchronous.  

    As soon as we dispatch an action the state is updated in the above example. But in real time apps we may need to do an API call before we update the state. These types of actions are called asynchronous actions or async actions.

    Now let’s see how async actions are handled.

    Handling async actions:

    For this, let’s make an API call to fetch some users.

    So, let’s go to the same project we have been working with, for the above example, and create a new file asyncActions.js and work in this file.

    To implement redux, we need 3 things as we have learnt:

    1. State
    2. Actions
    3. Reducers

    Let’s look at each one of them.

    State:

    The state object looks like this:

    The loading key in the state object is set to false initially, and it is used to show a spinner when we are making an API call.

    The users key in the state object is initially set to an empty array, as we get an array of users after making the API call.

    The error key in the state object is initially set to an empty string as if the API call fails, we get the error string and we store the error message in this error key.

    Actions:  

    The action types and the action creators can be written as shown below.

    The fetchUsersLoading action creator can be used when the API call is in progress. So, this returns action type FETCH_USERS_LOADING.

    The fetchUsersSuccess action creator can be used when the API call is successful. We get an array of users as an argument for this function which returns the users array as a payload along with action type FETCH_USERS_SUCCESS.

    The fetchUsersFail action creator can be used when the API call fails, and we get an error message string as an argument for this function which returns the error message as a payload along with the action type FETCH_USERS_FAIL.

    Reducer:

    The reducer for the given scenario can be written as shown below.

    As mentioned already, FETCH_USERS_LOADING denotes that the API call is going on so loading should be set to true.

    FETCH_USERS_SUCCESS denotes that the API call is done and was successful. We can set loading to false again and users to action.payload as we are sending users inside payload in the action creator.

    FETCH_USERS_FAIL denotes that the API call is done and failed. We set loading to false again and error to action.payload as we are sending the error message inside payload in the action creator. Users is sent to an empty array as we will not get any users from the API.

    Now the last step remaining is to create the redux store.

    Create the store in the same way as the previous example.

    Now let’s see how to make an api call and actually handle async actions.

    To make an api call we use axios. You can read more about axios here.

    To define async action creators we use redux-thunk. It is a middleware that must be used in the same way that we used logger in the previous example.

    Read more about redux-thunk here.

    We need to install both the packages in order to use them. For that, open the terminal and run the following command.

    Command: npm install axios redux-thunk

    Let’s apply redux-thunk middleware as shown below. By requiring the redux-thunk and making use of applyMiddleWare in the same way as the previous example, we get:

    Now let’s write our async action creator which dispatches action creators which we have created earlier.

    We will make use of this API.

    First import axios as shown below.

    Next, make an API call for the above-mentioned end point using axios in our async action creator as shown below.

    Here fetchUsers is our async action creator and as we are using redux-thunk we can define async action creators. Redux-thunk allows us to return a function which has access to dispatch method through the arguments so that we can dispatch actions.

    We dispatch fetchUsersLoading initially as we are making an api call.

    Once the api call is successful we dispatch fetchUsersSuccess along with users as argument.

    If the API call fails, we dispatch fetchUsersFail along with the error message.  

    This is our async action creator which dispatches the necessary synchronous actions whenever required.

    Now write a subscribe method as shown in the above image and dispatch fetchUsers at the last.

    In the terminal, to run the file use the below command.

    Command: node asyncActions.js

    You can see the list of users in the terminal as shown below.

    Redux-thunk is widely used middleware to handle side effects such as API calls and other async tasks. It's important that you should learn about this package.

    And that’s it! You have completed learning about Redux concepts.

    Next, we move on to learning how to integrate Redux with your React application.  

    Before we start learning to integrate redux with react, let’s take a look at what react redux is.

    What is React Redux?

    React is a UI library whereas Redux is a state management library. They both work independently. We cannot use Redux directly in a react application, so we use React Redux to bind Redux in our React applications.

    React Redux is the official Redux UI binding library for React. If you are using Redux and React together, you should also use React Redux to bind these two libraries.

    This means if we want to use React and Redux together, we also need to use React Redux to bind them together.  

    For more information on React Redux, check this link.

    Installation:

    To directly create a redux app, run the following command inside the terminal.

    Command: npx create-react-app my-app --template redux

    Navigate into the application using cd command and start making changes to the application.

    To integrate redux into an existing react project, run the following command inside the react project.

    Command: npm install redux react-redux

    This installs redux and react-redux packages to the React application and we can start integrating redux with react.

    We are going to follow the second method as we are going to integrate redux with the existing react application.

    Let’s try rebuilding the above example with a UI.

    We will start with the setup as shown below. This has been created using create-react-app and has been changed according to our needs.

    Folder structure:

    App.js:

    App.js has only one component called MealContainer.

    MealContainer.js:

    Now if you run the app using the npm start command you will see the similar UI in the browser.

    Now, let’s start with integrating redux with our react application.

    As mentioned above, install redux and redux-thunk by running the below command.

    Command: npm install redux react-redux

    After the installation, create a new folder inside src with the name redux. All our redux logic goes into this folder. Now inside this, I would like to create folders with the feature names as all the logic related to a particular feature can be kept organized in a single place. As we have only one feature by the name meals, create a folder with the name meals and 2 files with the names mealActions.js and mealTypes.js to create the actions and action types for this particular feature as shown below.

    Inside the mealTypes.js export the action type as shown below.

    Note: export keyword is used so that we are able to use the particular function or object in other files by importing them using import key word.

    Create an action creator to buy a meal as we have learnt in the previous example.

    Now let’s create reducer for our meals feature. For this, create a new file with the name mealReducer.js inside the same folder and create reducer for the meals feature.

    Now let’s create the redux store. For this, create a file with the name store.js inside redux folder as store is common for all the features. Next, create a store as we have already learnt, and export it as the default.

    Now that we have set up our redux for the application, how does our application get access to the store? Well, for that we need to go to the react-redux package we installed; this is where react-redux makes its first appearance. We need to go to Provider which react-redux offers in order to make our app know about the store.

    Go to the app.js file and import Provider from react-redux, and wrap the whole app with this provider passing store as a prop to it.

    Now what remains is to connect redux to our components, dispatch an action and update the store from the components.

    Connecting redux to the components:

    As a first step, write a couple of functions mapStateToProps and mapDispatchToProps as shown below.

    mapStateToProps is a function that you would use to provide the store data to the component as prop. Whereas mapDispatchToProps is something that you will use to provide the action creators as props to the component.

    Read more about the 2 functions here.

    We import buyMeal action from the action file to use in mapDispatchToProps.

    Now to connect both the functions to the component, we need to import connect which react-redux offers us as shown below.

    Now using that, we connect the state and actions to the component as shown below.

    mapStateToProps and mapDispatchToProps are passed as arguments to the connect function.

    Now we can access the numOfMeals using the props object and show that in the UI.

    The numOfMeals upon the props pertains to the key returned by the object in the mapStateToProps.

    If you save and check the UI, you can see the number of meals displayed.

    Now let’s dispatch our buyMeals action. This is available on the props object, as we have used mapDispatchToProps. Upon the click of the button, we execute the function which dispatches our action as shown below.

    Now if you click the button in the UI, the meals should decrease by 1.

    Now, let’s integrate logic for the snacks as well.  

    Add SnackContainer.js file similar to mealContainer and add it in the App.js file as shown below.

    In the redux folder, add a new folder for snacks feature and add the necessary files in the same manner as the meals folder.

    snackTypes.js

    snackActions.js

    Next, write the reducer in the snackReducer.js

    As we have 2 reducers, we need to combine reducers as we have learnt previously, and pass the rootReducer to the store.

    Due to this change, the application will break as we have changed the structure of the state in the store. So, we need to make some changes in mealContainer as shown below.

    Let’s connect the state to the snackContainer component in the same way that we have done in the mealContainer component, as shown below.

    If you check the UI, you will be able to see the number of snacks displayed as shown below.

    If we click on the Buy Snacks button, that should decrease the number of snacks by 1.

    And that’s it! We have implemented React-Redux along with the React UI.

    Let’s see how to manage Async actions in UI.

    If you see, we have rewritten the same code we have used to learn Redux.

    Let’s implement the same API call example we have learnt above in React. We will consider that these are the users who are using our restaurant.  

    Async Actions along with React UI:  

    Install the necessary packages as shown below.

    Command: npm install axios redux-thunk

    Create a user’s folder as we are adding user features to this application. In the user’s folder add usersTypes.js to add the types we have learnt in the async actions example we used while learning redux.

    Now let’s create the usersReducer in the same way that we have learnt.

    Add our async action creator as well.

    Now let’s create the usersReducer in the same way that we have learnt.

    Next, add our usersReducer to the combineReducers and configure redux-thunk middleware in store.js.

    And we are done with the redux-logic! Let’s add usersContainer.js file in the components folder, write the following code and add it to App.js.

    App.js now looks as shown below.

    Now let’s connect our state to the component as shown below.

    Now if you go to the UI and click the Load Users button, this should show up all the users names that we have fetched from the API.

    We are done!

    Reasons to use React Redux:

    • It is the official Redux UI Binding for React.
    • It encourages good React architecture.  
    • It implements Performance Optimizations  
    • It has great community support.

    Redux has its own drawbacks that need to be overcome. For this, Redux has come up with Redux-toolkit.

    An Introduction to Redux toolkit:

    The Redux Toolkit package is intended to be the standard way to write Redux logic. It was originally created to help address three common concerns about Redux:

    • "Configuring a Redux store is too complicated"
    • "I have to add a lot of packages to get Redux to do anything useful"
    • "Redux requires too much boilerplate code"

    Read more about redux-toolkit here.

    Installation:

    To create a new React app, along with Redux toolkit run the below command.

    Command: npx create-react-app my-app --template redux

    To add the Redux toolkit to an already existing app:

    Command: npm install @reduxjs/toolkit

    Other Resources:

    Link to learn more about React Redux.

    To read more about the connect function we have used.

    Learn React.

    Summary:

    In this blog you have all the information you need to work with React-Redux. You have learnt how to implement Redux, and understood the use of actions, reducers, store, action creators, middlewares. You would have understood how to handle async actions, combine reducers, integrate redux to react UI, connect components and also the use of Redux toolkit.

    Good luck with your React-Redux learning journey!

    Profile

    Bala Krishna Ragala

    Blog Author

    Bala Krishna Ragala, Head of Engineering at upGrad, is a seasoned writer and captivating storyteller. With a background in EdTech, E-commerce, and LXP, he excels in building B2C and B2B products at scale. With over 15 years of experience in the industry, Bala has held key roles as CTO/Co-Founder at O2Labs and Head of Business (Web Technologies) at Zeolearn LLC. His passion for learning, sharing, and teaching is evident through his extensive training and mentoring endeavors, where he has delivered over 80 online and 50+ onsite trainings. Bala's strengths as a trainer lie in his extensive knowledge of software applications, excellent communication skills, and engaging presentation style.

    Share This Article
    Ready to Master the Skills that Drive Your Career?

    Avail your free 1:1 mentorship session.

    Select
    Your Message (Optional)

    Upcoming Web Development Batches & Dates

    NameDateFeeKnow more
    Course advisor icon
    Course Advisor
    Whatsapp/Chat icon