Redux has greatly helped in reducing the complexities of state management. Its one way data flow is easier to reason about and it also provides a powerful mechanism to include middlewares which can be chained together to do our biding. One of the most common use case for the middleware is to make async calls in the application. Different middlewares like redux-thunk, redux-sagas, redux-observable, etc are a few examples. All of these come with their own learning curve and are best suited for tackling different scenarios.
The answer is Yes! This blog will try to explain on how to implement async action calls in redux without the use of any middlewares.
So let us first start by making a simple react project by using
Also we will be using
react-redux in addition to
redux to make our life a little easier. And to mock the APIs we will be using
We will just implement two API calls to not to over complicate things.
Create a new file called
api.js .It is the file in which we will keep the fetch calls to the endpoint.
Each API call has three base actions associated with it. Namely,
REQUEST, SUCCESS and FAIL. Each of our APIs will be in one of these three states at any given time. And depending on these states we can decide how to show our UI. Like when it is in
REQUEST state we can have the UI show a loader and when it is in
FAIL state we can show a custom UI to tell the user that something has went wrong.
So we create three constants of
REQUEST, SUCCESS and FAIL for each API call which we will be making. In our case the
constants.js file will look something like this:
store.js file and the
initialState of our application is as follows:
As can be seen from the above code, each of our APIs data lives in one object the the
state object. Keys
isLoading tells us if the API is in the
Now as we have our
store defined, let us see how we will manipulate the
statewith different phases that an API call can be in. Below is our
By giving each individual API call its own variable to denote the loading phase we can now easily implement something like multiple loaders in the same screen according to which API call is in which phase.
dispatch as the first argument. But why do we have to pass
dispatch to the function? Because it needs to dispatch actions to the store. Normally a component has access to
dispatch but since we want an external function to take control over dispatching, we need to give it control over dispatching.
And a function to give
dispatch in the above function’s scope:
So now our complete
actions.js file looks like this:
Once this is done, all that is left to do is to pass these functions in
mapDispatchToProps of our connected component.
App.js file looks like the one below:
This is how we do async calls without middlewares in redux. This is a much simpler approach than using a middleware and the learning curve associated with it. If this approach covers all your use cases then by all means use it.
This type of approach really shines when you have to make a simple enough application like a demo of sorts, where API calls is all the side-effect that you need. In larger and more complicated applications there are a few inconveniences with this approach. First we have to pass
dispatch around to which seems kind of yucky. And also we have to remember which call requires dispatch and which do not.
The full code can be found here.
About the Author
Abhishek is a R&D engineer at Velotio. He is a full-stack developer working on both the web and mobile front. He has a keen interest in theoretical computer science and likes to read in his free time.