Asynchronous Redux Without Middlewares — Using ES2017

André Gardi
Mar 21 · 3 min read

It is possible to handle asynchronous redux actions without middlewares and, with ES2017 async/await, we can do it in an even more clear way.

Should I do it?

I am not here to say that you shouldn’t use thunk or saga. If you prefer, you can think of it as an exercise to help us to deepen our knowledge of redux and functional programming. Also, we are going to do it all in a testable way.

The project

We are going to create a simple React project to consume the GitHub API to search repositories by username. If you want to see how the final product looks like, visit the link below:

https://async-redux-without-middleware.herokuapp.com

Let’s code

We are going to use create-react-app CLI:

npx create-react-app async-redux-without-middlewares
cd async-redux-without-middlewares

Let’s also install the dependencies

npm install -s redux react-redux axios

The http service

Services are created to separate the http requests from the business logic. On top of that, we are going to add an abstraction layer, exporting not the service object, but a function that generates the service object. This allows us to isolate the axios dependency helping us to test the service without having to actually call the http request.

services/repos.js

The action

actions/repos.js

The exported function getReposByUsernameInjector is the one that is going to be used to connect() our main container. It will not be referenced, but executed, and its result will become a property of the component.

Receiving all dependencies of getReposByUsernameas parameters, isolates the function, allowing us to write tests without having to import the store or actually calling our service.

Connecting

In react, containers are components that connects to the redux state. For didactic reasons we are going to separate the connection from the component itself.

components/Main.js

containers/ConnectedMain.js

The second parameter of connect() is a function called mapDispatchToProps, which lets you create functions that dispatch when called, and pass the resulting object properties as props to your component.

If you want to learn more about actions dispatching, I really recommend reading this page from the redux documentation.

After connecting it all, the flow look like this:

Click to expand

How do I test it?

The service

To test our service, we just need to call a custom object as the axios and expect that the get() function is called with the repos url.

services/repos.test.js

The action

To test our action, we will setup a custom dispatch() and service to simulate the four possibilities: success, empty repos, username not found and connection error.

actions/repos.test.js

The container

Because we separate our connection container from the component, it is easier to test it separately.

The other components

There are more code files to cover all the project. But those are simple implementation of basic React. Comment it now would be out of context, besides making this article too long. If you want to explore more details, here is the GitHub repository:

Note: I added, to the final project,@material-ui/core and @material-ui/icons for visual components and expressto host static servers on Heroku.

JavaScript in Plain English

Learn the web's most important programming language.

André Gardi

Written by

JavaScript in Plain English

Learn the web's most important programming language.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade