Redux – Middleware

Redux itself is synchronous, so how the async operations like network request work with Redux? Here middlewares come handy. As discussed earlier, reducers are the place where all the execution logic is written. Reducer has nothing to do with who performs it, how much time it is taking or logging the state of the app before and after the action is dispatched.

In this case, Redux middleware function provides a medium to interact with dispatched action before they reach the reducer. Customized middleware functions can be created by writing high order functions (a function that returns another function), which wraps around some logic. Multiple middlewares can be combined together to add new functionality, and each middleware requires no knowledge of what came before and after. You can imagine middlewares somewhere between action dispatched and reducer.

Commonly, middlewares are used to deal with asynchronous actions in your app. Redux provides with API called applyMiddleware which allows us to use custom middleware as well as Redux middlewares like redux-thunk and redux-promise. It applies middlewares to store. The syntax of using applyMiddleware API is −

applyMiddleware(...middleware)

And this can be applied to store as follows −

import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './reducers/index';
const store = createStore(rootReducer, applyMiddleware(thunk));

Middlewares will let you write an action dispatcher which returns a function instead of an action object. Example for the same is shown below −

function getUser() {
   return function() {
      return axios.get('/get_user_details');
   };
}

Conditional dispatch can be written inside middleware. Each middleware receives store’s dispatch current state and return a function. Any return value from an inner function will be available as the value of dispatch function itself.

The getState function is useful to decide whether new data is to be fetched or cache result should get returned, depending upon the current state.

Let us see an example of a custom middleware logger function. It simply logs the action and new state.

import { createStore, applyMiddleware } from 'redux'
import userLogin from './reducers'

function logger({ getState }) {
   return next => action => {
      console.log(‘action’, action);
      const returnVal = next(action);
      console.log('state when action is dispatched', getState()); 
      return returnVal;
   }
}

Now apply the logger middleware to the store by writing the following line of code −

const store = createStore(userLogin , initialState=[ ] , applyMiddleware(logger));

Dispatch an action to check the action dispatched and new state using the below code −

store.dispatch({
   type: 'ITEMS_REQUEST', 
	isLoading: true
})

Related Posts

What are custom events in JavaScript?

Custom events are the events that allow you to decouple the code you want to run after a specific piece of code runs. There are various in-built events…

How to use nested for loop in JavaScript?

We use the for loop statement of JavaScript for repeating a set of statements inside the loop body a specified number of times. A nested for loop, as the…

What are the basic rules for JavaScript parameters?

A JavaScript function is a code that performs a particular task. The function parameters are the name list in the function definition. Parameters are also known as…

How to stop refreshing the page on submit in JavaScript?

Using event.preventDefault() to stop page refresh on form submit In this section, we will see how to use event.preventDefault() to stop page refresh on form submission. The event.preventDefault() restricts the default…

Target a Window Using JavaScript or HTML

TARGET attribute of HTML A link’s opening named frame or window is specified using the Target attribute of the <a> anchor tag. The concluding </a> tag in…

What is the role of deferred scripts in JavaScript?

Since JavaScript is a loosely typed language, you are not required to correctly predict the kind of data that will be kept in a variable. Depending on the information…