Search

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 –yesThere 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 reduxIf 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 indexIt 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:StoreAction  ReducerWe 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:Store: The store holds all the states of the application. This is similar to the restaurant holding all the meals.  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.  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: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}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”}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 caseAnd 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 belowHere, 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-loggerNow 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:StateActionsReducersLet’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-thunkLet’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.jsYou 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 reduxNavigate 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-reduxThis 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-reduxAfter 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.jssnackActions.jsNext, write the reducer in the snackReducer.jsAs 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-thunkCreate 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 reduxTo add the Redux toolkit to an already existing app:Command: npm install @reduxjs/toolkitOther 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!

What is React Redux?

6K
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!

KnowledgeHut

KnowledgeHut

Author

KnowledgeHut is an outcome-focused global ed-tech company. We help organizations and professionals unlock excellence through skills development. We offer training solutions under the people and process, data science, full-stack development, cybersecurity, future technologies and digital transformation verticals.
Website : https://www.knowledgehut.com

Join the Discussion

Your email address will not be published. Required fields are marked *

Suggested Blogs

Handling React Events - A Detailed Guide

Event handling essentially allows the user to interact with a webpage and do something specific when a certain event like a click or a hover happens. When the user interacts with the application, events are fired, for example, mouseover, key press, change event, and so on. The application must handle events and execute the code. In short, events are the actions to which javascript can respond.   The actions to which javascript can respond are called events. Handling events with react is  very similar to handling events in DOM elements. Below are some general events that you would see in and out when dealing with react based websites:  Clicking an element  Submitting a form Scrolling page Hovering an element  Loading a webpage Input field change User stroking a key Image loading Naming Events in React Handling events with react is very similar to handling events in DOM elements, although there are some syntactic differences.   React events are written in camelCase.   A function is passed as the event handler rather than string. The way to write events in html / DOM is below:        click me onclick is written in lower case in html as shown above and what action to take when this onclick event triggers is taken care of by handleClick.In React, events are named using camel case and you pass a function as event handler as shown below:  Like in a functional component, event is written like below:       click me   In class based component ,event is written like below        click me Defining Events:Events are normally used in combination with functions, and the function is not executed until the event occurs, and the combination of event, HTML element, and javascript function is called binding which means to map all three. Generic syntax is:      Example:  Create a button element and what happens when onClick event triggered is driven by the function which is func() shown below     click me Let’s see some of the event attributes:   onmouseover : The mouse is moved over an element onmouseup : The mouse button is released onmouseout : The mouse  is moved off an element onmousemove: The mouse is moved Onmousedown: mouse button is pressed  onload : A image is done loading onunload: Existing the page  onblur : Losing Focus  on element  onchange : Content of a field changes onclick: Clicking an object  ondblclick: double clicking an object  onfocus element getting a focus  Onkeydown: pushing a keyboard key Onkeyup: keyboard key is released Onkeypress: keyboard key is pressed  Onselect: text is selected These are some examples of events:                                         Events                               function testApp (){                        alert((“Hello Event”);                                                   test Clicked                  test double Clicked                     Synthetic Events When you specify an event in JSX, you are not directly dealing with regular DOM events, you are dealing with a react event type called a synthetic event.It's a simple wrapper for native event instances and every synthetic event created needs to be garbage-collected which can be resource intensive in terms of CPU. The synthetic event object has properties mentioned below:  Boolean isTrusted  DOMEvent nativeEvent number timeStamp   void preventDefault() number eventPhase Synthetic events provide an interface and reduce browser inconsistencies and the event contains required information for its propagation to work. Synthetic event is reused for performance reasons in the browser, A synthetic event is a cross-browser wrapper around the browser’s native event it has the same interface as the native event. Synthetic events are delegated to the document node. Therefore native events are triggered first and the events bubble up to document, after which the synthetic events are triggered. The synthetic event object will be reused and all the properties will be nullified after the event callback has been invoked and this is for performance reasons.The workflow of synthetic event in react is:    Element ---- > Event ---- > synthetic event  ---- > handler(e)                                |                                                      |                                |  _______  Component ________|  umber timeStamp The Basics of React Event Handling Let’s explore how to handle events in react and we will showcase the click event and how it holds good for other types of events. Let’s start with functional components by creating a  file as clickAppHandler.js.In this file let’s create a  functional component  as shown below                        Import React from ‘...react’                         function clickAppHandler() {                                function clickHandler() {                                        console.log(‘clicked’)                                         }                                  return (                                                                                  Click                                                                          )                         }                       export default clickAppHandler  When onClick event triggers clickHandler function is called as shown below and when you click the button console will print the string “clicked” After this you need the add a component in the app component. In our code above you can see on click we pass the function as event handler and you will notice that we haven't added parentheses as it becomes a function, and we do not want that and we want handler to be a function not a function call. When a new component is rendered its event handler functions are added to the mapping maintained by the react.When the event is triggered and it hits and DOM object ,react maps the event to the handler, if it matches it calls the handler. The event handling in react is declarative and the advantage of declarative way to handlers is that they are part of the User interface structure.  Let’s take a look at event handling in class components                       Import React, { Component } from ‘...react’                         class TestApp extends Component {                              clickHandler() {                                  console.log(“clicked”)                                }                                render(){                                      return(                                                                                     Click me                                                                                 )                                 }                            }                       export default TestApp You cannot return false to prevent default behaviour in React. You must call preventDefault explicitly.  In HTML it looks like below:    Click Output: It will print “Clicked”  And in React, like this:  function clickHandle(e) {       e.preventDefault();       console.log(“Handled”);   }  Click  Output : console will print “Handled”  There are some  event handlers triggered by an event in the bubbling phase which is the same as with the normal DOM API; simply attach a handler to an eventual parent of an element and any events triggered on that element will bubble to the parent as long as it's not stopped via stopPropagation along the way   Click me  Below are some of the event handlers triggered in the bubbling phase:  MouseEvents           onClick           onDrag          onDoubleClick Keyboard Events                    onKeyDown                    onKeyPress                    onKeyUp Focus Events                  onFocus   onBlur To capture an event handler for the capture phase, append capture to the event name. For example, instead of using onClick, use onClickCapture to handle the click event.  Capture event example:                  Click me    Additional ExamplesExample1                       Import React from ‘...react’                         function clickAppHandler() {                                function clickHandler() {                                        console.log(‘clicked’)                                         }                                  return (                                                                                  Click                                                                          )                         }                       export default clickAppHandler   Example2       This example is along with HTML in a single file                                                            Events                               function testApp (){                        alert((“Hello Event”);                                                   test Clicked                  test double Clicked                     Adding Events: Below example is how you add an event. Highlighted in bold                      Import React from ‘...react’                         function clickAppHandler() {                                function clickHandler() {                                        console.log(‘clicked’)                                         }                                  return (                                                                                  Click                                                                          )                         }                       export default clickAppHandler  Passing Arguments to Event HandlerThere are two ways arguments are passed to event handler  Arrow function                    this.handleClick(id,e)}>Click                onClick is the event                e is the event object                 id can be state or props or some data Bind method      Click  In this case event object is automatically passed In both methods e represents the react event and its passed after the ID as second argument,With an arrow function this event e is passed explicitly but with bind method its automatically passed.                                     Import React,{ Component } from “react”;                                         class TestApp extends Component {                                           state = {                                                       id: 2,                                                      Name: “TestApp Dummy”                                                };                                                             //arrow function                                                 handleClick = (id,e) => {                                                       console.log(id);                                                       console.log(e);                                                  };                                               handleArg = (e) => { this.handleClick(this.state.id,e);}                                                          render() {     return (                    TestApp,{this.state.name}            onClick={this.handleArg}>Display            );   }  }  The react event is an object and obtained from react. Instead of creating a separate function for passing argument, you can directly pass the anonymous arrow function as shown in the render function below:     render() {        return (                                                                                                       TestApp,{this.state.name}                                                {                           this.handleClick(this.state.id,e);                                                               }}>Display                                                                                                         );                                                 }                                            }    Output:   click on button  “TestApp Dummy “                   Let’s see only how bind method looks like in the render function    render() {                                         return (                                                                                                 TestApp,{this.state.name}                                                   Display                                                                                                       );                                                  }                                              } Output: this will display the h1 tag and when you click the button handleClick function gets invoked and the console will display id of the state object as shown above. Building a Practice to Thoroughly Understand Events This blog focuses on event handling, which in turn teaches about event handlers declared in JSX markup.This approach helps in tracking down the element mapped with events in an easy way.  We also learned how to handle multiple event handlers in a single element by using JSX attributes.we also learned about ways to bind event handler and  parameter values. Then we learned about synthetic events which are abstractions around native events. The best way you can retain this learning is by practicing more and tackling the complexities that may arise as you practice. You can find several tutorials on the internet or share your questions with us here. Happy learning! 
5355
Handling React Events - A Detailed Guide

Event handling essentially allows the user to inte... Read More

MongoDB Query Document Using Find() With Example

MongoDB's find() method selects documents from a collection or view and returns a cursor to those documents. There are two parameters in this formula: query and projection.Query – This is an optional parameter that specifies the criteria for selection. In simple terms, a query is what you want to search for within a collection.Projection – This is an optional parameter that specifies what should be returned if the query criteria are satisfied. In simple terms, it is a type of decision-making that is based on a set of criteria.MongoDB's Flexible SchemaA NoSQL database, which stands for "not only SQL," is a way of storing and retrieving data that is different from relational databases' traditional table structures (RDBMS).When storing large amounts of unstructured data with changing schemas, NoSQL databases are indeed a better option than RDBMS. Horizontal scaling properties of NoSQL databases allow them to store and process large amounts of data.These are intended for storing, retrieving, and managing document-oriented data, which is frequently stored in JSON format (JavaScript Object Notation). Document databases, unlike RDBMSs, have a flexible schema that is defined by the contents of the documents.MongoDB is one of the most widely used open-source NoSQL document databases. MongoDB is known as a 'schemaless' database because it does not impose a specific structure on documents in a collection.MongoDB is compatible with a number of popular programming languages. It also offers a high level of operational flexibility because it scales well horizontally, allowing data to be spread or 'sharded' across multiple commodity servers with the ability to add more servers as needed. MongoDB can be run on a variety of platforms, including developer laptops, private clouds, and public clouds.Querying documents using find()MongoDB queries are used to retrieve or fetch data from a MongoDB database. When running a query, you can use criteria or conditions to retrieve specific data from the database.The function db.collection is provided by MongoDB. find() is a function that retrieves documents from a MongoDB database.In MongoDB, the find method is used to retrieve a specific document from the MongoDB collection. In Mongo DB, there are a total of six methods for retrieving specific records.find()findAndModify()findOne()findOneAndDelete()findOneAndReplace()findOneAndUpdate()Syntax:find(query, projection)We can fetch a specific record using the Find method, which has two parameters. If these two parameters are omitted, the find method will return all of the documents in the MongoDB collection.Example:Consider an example of employees with the database of employee_id and employee_name and we will fetch the documents using find() method.First, create a database with the name “employees” with the following code:use employeesNow, create a collection “employee” with:db.createCollection("employee")In the next step we will insert the documents in the database:db.employee.insert([{employee_id: 101, employee_name: "Ishan"}, {employee_id: 102, employee_name: "Bhavesh"}, {employee_id: 103, employee_name: "Madan"}])Find all Documents:To get all the records in a collection, we need to use the find method with an empty parameter. In other words, when we need all the records, we will not use any parameters.db.employee.find()Output in Mongo ShellThe pretty() method can be used to display the results in a formatted manner.Syntax:db.COLLECTION_NAME.find().pretty()Let’s check our documents with pretty() method:Query FiltersWe will see examples of query operations using the db.collection.find() method in mongosh.We will use the employee collection in the employees database.db.employee.insert([{employee_id: 101, employee_name: "Ishan", age: 21, email_id: "ishanjain@gmail.com"}, {employee_id: 102, employee_name: "Bhavesh", age: 22, email_id: "bhaveshg@gmail.com"}, {employee_id: 103, employee_name: "Madan", age: 23, email_id: "madan@gmail.com"}])As we have seen earlier that to select all the documents in the database we pass an empty document as the query filter parameter to the find method.db.employee.find().pretty()Find the first document in a collection:db.employee.findOne()Find a document by ID:db.employee.findOne({_id : ObjectId("61d1ae0b56b92c20b423a5a7")})Find Documents that Match Query Criteriadb.employee.find({“age”: “22”})db.employee.find({"employee_name": "Madan"}).pretty()Sort Results by a Field:db.employee.find().sort({age: 1}).pretty()order by age, in ascending orderdb.employee.find().sort({age: -1}).pretty()order by age, in descending orderAND Conditions:A compound query can specify conditions for multiple fields in the documents in a collection. A logical AND conjunction connects the clauses of a compound query indirectly, allowing the query to select all documents in the collection that meet the specified conditions.In the following example, we will consider all the documents in the employee collection where employee_id equals 101 and age equals 21.db.employee.find({"employee_id": 101, "age": "21" }).pretty()Querying nested fieldsThe embedded or nested document feature in MongoDB is a useful feature. Embedded documents, also known as nested documents, are documents that contain other documents.You can simply embed a document inside another document in MongoDB. Documents are defined in the mongo shell using curly braces (), and field-value pairs are contained within these curly braces.Using curly braces, we can now embed or set another document inside these fields, which can include field-value pairs or another sub-document.Syntax:{ field: { field1: value1, field2: value2 } }Example:We have a database “nested” and in this database we have collection “nesteddoc”.The following documents will insert into the nesteddoc collection.db.nesteddoc.insertMany([ { "_id" : 1, "dept" : "A", "item" : { "sku" : "101", "color" : "red" }, "sizes" : [ "S", "M" ] }, { "_id" : 2, "dept" : "A", "item" : { "sku" : "102", "color" : "blue" }, "sizes" : [ "M", "L" ] }, { "_id" : 3, "dept" : "B", "item" : { "sku" : "103", "color" : "blue" }, "sizes" : "S" }, { "_id" : 4, "dept" : "A", "item" : { "sku" : "104", "color" : "black" }, "sizes" : [ "S" ] } ])Place the documents in the collection now. Also, take a look at the results:As a result, the nesteddoc collection contains four documents, each of which contains nested documents. The find() method can be used to access the collection's documents.db.nesteddoc.find()Specify Equality Condition:In this example, we will select the document from the nesteddoc query where dept equals “A”.db.nesteddoc.find({dept: "A"})Querying ArraysUse the query document {: } to specify an equality condition on an array, where is the exact array to match, including the order of the elements.The following query looks for all documents where the field tags value is an array with exactly two elements, "S" and "M," in the order specified:db.nesteddoc.find( { sizes: ["S", "M"] } )Use the $all operator to find an array that contains both the elements "S" and "M," regardless of order or other elements in the array:db.nested.find( { sizes: { $all: ["S", "M"] } } )Query an Array for an Element:The following example queries for all documents where size is an array that contains the string “S” as one of its elements:db.nesteddoc.find( { sizes: "S" } )Filter conditionsTo discuss the filter conditions, we will consider a situation that elaborates this. We will start by creating a collection with the name “products” and then add the documents to it.db.products.insertMany([ { _id: 1, item: { name: "ab", code: "123" }, qty: 15, tags: [ "A", "B", "C" ] }, { _id: 2, item: { name: "cd", code: "123" }, qty: 20, tags: [ "B" ] }, { _id: 3, item: { name: "ij", code: "456" }, qty: 25, tags: [ "A", "B" ] }, { _id: 4, item: { name: "xy", code: "456" }, qty: 30, tags: [ "B", "A" ] }, { _id: 5, item: { name: "mn", code: "000" }, qty: 20, tags: [ [ "A", "B" ], "C" ] }])To check the documents, use db.products.find():$gt$gt selects documents with a field value greater than (or equal to) the specified value.db.products.find( { qty: { $gt: “20” } } )$gte:$gte finds documents in which a field's value is greater than or equal to (i.e. >=) a specified value (e.g. value.)db.products.find( { qty: { $gte: 20 } } )$lt:$lt selects documents whose field value is less than (or equal to) the specified value.db.products.find( { qty: { $lt: 25 } } )$lte:$lte selects documents in which the field's value is less than or equal to (i.e. =) the specified value.db.products.find( { qty: { $lte: 20 } } )Query an Array by Array Length:To find arrays with a specific number of elements, use the $size operator. For example, the following selects documents with two elements in the array.db.products.find( { "tags": {$size: 2} } )ProjectionIn MongoDB, projection refers to selecting only the data that is required rather than the entire document's data. If a document has five fields and you only want to show three of them, select only three of them.The find() method in MongoDB accepts a second optional parameter, which is a list of fields to retrieve, as explained in MongoDB Query Document. When you use the find() method in MongoDB, it displays all of a document's fields. To prevent this, create a list of fields with the values 1 or 0. The value 1 indicates that the field should be visible, while 0 indicates that it should be hidden.Syntax:db.COLLECTION_NAME.find({},{KEY:1})Example:We will consider the previous example of products collection. Run the below command on mongoshell to learn how projection works:db.products.find({},{"tags":1, _id:0})Keep in mind that the _id field is always displayed while executing the find() method; if you do not want this field to be displayed, set it to 0.Optimized FindingsTo retrieve a document from a MongoDB collection, use the Find method.Using the Find method, we can retrieve specific documents as well as the fields that we require. Other find methods can also be used to retrieve specific documents based on our needs.By inserting array elements into the query, we can retrieve specific elements or documents. To retrieve data for array elements from the collection in MongoDB, we can use multiple query operators.
6495
MongoDB Query Document Using Find() With Example

MongoDB's find() method selects documents from a c... Read More

Implementing MongoDb Map Reduce using Aggregation

Algorithms and applications in today's data-driven market collect data about people, processes, systems, and organisations 24 hours a day, seven days a week, resulting in massive amounts of data. The problem is figuring out how to process this massive amount of data efficiently without sacrificing valuable insights.What is Map Reduce? The MapReduce programming model comes to the rescue here. MapReduce, which was first used by Google to analyse its search results, has grown in popularity due to its ability to split and process terabytes of data in parallel, generating results faster. A (Key,value) pair is the basic unit of information in MapReduce. Before feeding the data to the MapReduce model, all types of structured and unstructured data must be translated to this basic unit. The MapReduce model, as the name implies, consists of two distinct routines: the Map-function and the Reduce-function.  MapReduce is a framework for handling parallelizable problems across huge files using a huge number of devices (nodes), which are collectively referred to as a cluster (if all nodes are on the same local network and use similar hardware) or a grid (if the nodes are shared across geographically and administratively distributed systems, and use more heterogeneous hardware).  When data stored in a filesystem (unstructured) or a database(structured) is processed, MapReduce can take advantage of data's locality, processing it close to where it's stored to reduce communication costs. Typically, a MapReduce framework (or system) consists of three operations: Map: Each worker node applies the map function to local data and saves the result to a temporary storage. Only one copy of the redundant input data is processed by a master node. Shuffle: worker nodes redistribute data based on output keys (produced by the map function), ensuring that all data associated with a single key is stored on the same worker node. Reduce: each group of output data is now processed in parallel by worker nodes, per key. This article will walk you through the Map-Reduce model's functionality step by step. Map Reduce in MongoDB The map-reduce operation has been deprecated since MongoDB 5.0. An aggregation pipeline outperforms a map-reduce operation in terms of performance and usability. Aggregation pipeline operators like $group, $merge, and others can be used to rewrite map-reduce operations. Starting with version 4.4, MongoDB provides the $accumulator and $function aggregation operators for map-reduce operations that require custom functionality. In JavaScript, use these operators to create custom aggregation expressions. The map and reduce functions are the two main functions here. As a result, the data is independently mapped and reduced in different spaces before being combined in the function and saved to the specified new collection. This mapReduce() function was designed to work with large data sets only. You can perform aggregation operations like max and avg on data using Map Reduce, which is similar to groupBy in SQL. It works independently and in parallel on data. Implementing Map Reduce with Mongosh (MongoDB Shell)  The db.collection.mapReduce() method in mongosh is a wrapper for the mapReduce command. The examples that follow make use of the db.collection.mapReduce(). Example: Create a collection ‘orders’ with these documents: db.orders.insertMany([     { _id: 1, cust_id: "Ishan Jain", ord_date: new Date("2021-11-01"), price: 25, items: [ { sku: "oranges", qty: 5, price: 2.5 }, { sku: "apples", qty: 5, price: 2.5 } ], status: "A" },     { _id: 2, cust_id: "Ishan Jain", ord_date: new Date("2021-11-08"), price: 70, items: [ { sku: "oranges", qty: 8, price: 2.5 }, { sku: "chocolates", qty: 5, price: 10 } ], status: "A" },     { _id: 3, cust_id: "Bhavesh Galav", ord_date: new Date("2021-11-08"), price: 50, items: [ { sku: "oranges", qty: 10, price: 2.5 }, { sku: "pears", qty: 10, price: 2.5 } ], status: "A" },     { _id: 4, cust_id: "Bhavesh Galav", ord_date: new Date("2021-11-18"), price: 25, items: [ { sku: "oranges", qty: 10, price: 2.5 } ], status: "A" },     { _id: 5, cust_id: "Bhavesh Galav", ord_date: new Date("2021-11-19"), price: 50, items: [ { sku: "chocolates", qty: 5, price: 10 } ], status: "A"},     { _id: 6, cust_id: "Madan Parmar", ord_date: new Date("2021-11-19"), price: 35, items: [ { sku: "carrots", qty: 10, price: 1.0 }, { sku: "apples", qty: 10, price: 2.5 } ], status: "A" },     { _id: 7, cust_id: "Madan Parmar", ord_date: new Date("2021-11-20"), price: 25, items: [ { sku: "oranges", qty: 10, price: 2.5 } ], status: "A" },     { _id: 8, cust_id: "Abhresh", ord_date: new Date("2021-11-20"), price: 75, items: [ { sku: "chocolates", qty: 5, price: 10 }, { sku: "apples", qty: 10, price: 2.5 } ], status: "A" },     { _id: 9, cust_id: "Abhresh", ord_date: new Date("2021-11-20"), price: 55, items: [ { sku: "carrots", qty: 5, price: 1.0 }, { sku: "apples", qty: 10, price: 2.5 }, { sku: "oranges", qty: 10, price: 2.5 } ], status: "A" },     { _id: 10, cust_id: "Abhresh", ord_date: new Date("2021-11-23"), price: 25, items: [ { sku: "oranges", qty: 10, price: 2.5 } ], status: "A" }  ]) Apply a map-reduce operation to the orders collection to group them by cust_id, then add the prices for each cust_id: To process each input document, define the map function: this refers the document that the map-reduce operation is processing in the function. For each document, the function maps the price to the cust_id and outputs the cust_id and price. var mapFunction1 = function() {emit(this.cust_id, this.price);}; With the two arguments keyCustId and valuesPrices, define the corresponding reduce function: The elements of the valuesPrices array are the price values emitted by the map function, grouped by keyCustId. The valuesPrice array is reduced to the sum of its elements by this function. var reduceFunction1 = function(keyCustId, valuesPrices) {return Array.sum(valuesPrices);};Apply the mapFunction1 map function and the reduceFunction1 reduce function to all documents in the orders collection: db.orders.mapReduce(mapFunction1,reduceFunction1,{ out: "map_reduce_example" }) The results of this operation are saved in the map_reduce_example collection. If the map_reduce_example collection already exists, the operation will overwrite its contents with the map-reduce operation's results. Check the map_reduce_example collection to verify: db.map_reduce_example.find().sort( { _id: 1 } ) Aggregation Alternative:You can rewrite the map-reduce operation without defining custom functions by using the available aggregation pipeline operators: db.orders.aggregate([{$group: { _id:"$cust_id",value:{$sum: "$price" } } },{ $out: "agg_alternative_1" }]) Check the agg_alternative_1 collection to verify: db.agg_alternative_1.find().sort( { _id: 1 } )Implementing Map Reduce with Java Consider the collection car and insert the following documents in it. db.car.insert( [ {car_id:"c1",name:"Audi",color:"Black",cno:"H110",mfdcountry:"Germany",speed:72,price:11.25}, {car_id:"c2",name:"Polo",color:"White",cno:"H111",mfdcountry:"Japan",speed:65,price:8.5}, {car_id:"c3",name:"Alto",color:"Silver",cno:"H112",mfdcountry:"India",speed:53,price:4.5}, {car_id:"c4",name:"Santro",color:"Grey",cno:"H113",mfdcountry:"Sweden",speed:89,price:3.5} , {car_id:"c5",name:"Zen",color:"Blue",cno:"H114",mfdcountry:"Denmark",speed:94,price:6.5} ] ) You will get an output like this:  Let's now write the map reduce function on a collection of cars, grouping them by speed and classifying them as overspeed cars.  var speedmap = function (){  var criteria;  if ( this.speed > 70 ) {criteria = 'overspeed';emit(criteria,this.speed);}}; Based on the speed, this function classifies the vehicle as an overspeed vehicle. The term "this" refers to the current document that requires map reduction. var avgspeed_reducemap = function(key, speed) {       var total =0;       for (var i = 0; i 
7344
Implementing MongoDb Map Reduce using Aggregation

Algorithms and applications in today's data-driven... Read More