Redux Middlewares — An approach to cancel redux actions

Sumit Gupta
Treebo Tech Blog
Published in
5 min readMay 4, 2018

Redux is an excellent tool for managing the state of an application. The unidirectional data flow makes the state changes very predictable. If you want to change the state of an application, you fire an action which causes the reducer to output a new state with the desired changes. However, as the application grows it becomes increasingly difficult to manage the code.

One such problem we faced at Treebo, across all our platforms was redundant or stale redux actions. In this blog post I am going to interchangeably use async redux actions and API calls.

Let’s look at the different scenarios which lead to this problem:

  • Spam: A user can click on a button repeatedly, button click in turn can lead to several async redux actions of same type. In the example below, a user can click on confirm button repeatedly.
    Solutions: a) Disable the button while waiting for the API to resolve. b) Use debounce. If I have to vote for one solution, I would vote for the first one.
  • Rapid transition b/w page: Treebo app’s landing page has a popular cities section. On clicking one of the cities the user is redirected to results page. Results page shows hotels for the selected city, fetching hotel results and prices taking an average time of 2 seconds. In the meantime, if the user goes back and again clicks on one of the popular cities, he will again land on the results page but with a different city. On his second visit, user will get hotel results of two cities - previously selected city and the current one.
    Solution: On the cities page filter through the results and show only results belonging to the currently selected city.
  • Multiple clicks during animation: On popular cities section, a user can click on two cities in quick succession while we are showing animation to load the results page. In this case also the results page will have hotels results of both the cities.
    Solution: Use debounce so only one city click is processed for a given duration.

Analysing the solutions so far:

We have devised a number of solutions above, they all seem to fix the problem but the solutions are scattered all over the codebase and we are coupling our view logic with state management logic because of the problems related to async redux actions. This is undesirable. For example:

On click of popular city we have added debounce. The main problem here is that code is human readable but not human understandable. It will take a fellow engineer hours of banging his head (though not on a wall) to understand it is because of asynchronous redux actions.

Is there a solution possible where we can address all the above mentioned problems and similar problems in one go? Yes, there is. It can be done with the help of Redux middleware. Redux middleware provides a third party extension between dispatching an action and the moment it reaches the reducer. It is similar to the middlewares present in “express” and “koa” and even though it solves a different problem, it is conceptually the same.

To implement a solution for cancelling of asynchronous redux actions, we first need to understand how an asynchronous redux action works.

Declaration of action types:

Action Types

Each asynchronous action has three action types associated with it, which is also synonymous to the three phases of an API request. The start of the request followed by success or failure of the request.

Declaring an action :

Action

Listen to actions in reducer:

Reducer

A middleware for cancelling redux actions

Now since we have understood asynchronous redux actions, let’s implement a middleware which can intercept actions of similar types and remove the stale ones.

To implement this solution we need to assign a unique id to each redux action. I am going to use redux-pack as a middleware for this. It will help us in following ways

  • Saves us from writing a lot of code for each async redux action
  • Is a great example of redux middleware
  • Last but not the least, it helps us in assigning each new action a unique id

An example of async action with redux-pack

Async action with redux-pack

Now, the only part left is coding our middleware.

Conclusion:

I hope this post helped you get a feel for why redux middleware matters, how to use them, and most importantly *when* to use them.

Redux middleware is a powerful tool and should be used carefully. Identifying a cross cutting concern and solving it using Redux middleware is quite exciting.

More questions? Ping me in the comments to keep the conversation going or reach out to me on Twitter.

Follow us for more such posts from Treebo and staying on top of how product and technology is shaping the hospitality industry!

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Written by Sumit Gupta

Senior Frontend Engineer @TreeboHotels, Learning front-end one step at a time.

Responses (2)

What are your thoughts?