async actions in react-redux

icecoffee

Atulit Anand

Posted on August 12, 2021

async actions in react-redux

Redux is a widely opinionated tool for state management. Although it's not exclusively made for react but it's praised by a lot of react developers.

Redux uses a big javascript object called the state tree to store and preserve the global state of the application.

Which we can access via dispatching actions to the reducer.

Reducer is a special function and in a higher-level language, I can say reducer is something that takes the original part of the state that it needs to work on and the action that you want it to do and gives away the result. Like a black box.

Now this is a very beautiful concept but you can not do something like this.

const reducer = async (state = initialState, action) => {
    let { users } = state;
    if (action.type === LOAD_USER) {
        const userData = await loadUser(...);
        users.push(userData)
        return { ...state, loading: true }
    }
}
Enter fullscreen mode Exit fullscreen mode

To fetch and update state tree with async data, the traditional way is to use applyMiddleWare or some 3rd partly library like redux-thunk. But I won't be using that.

To bypass all the fuss we'll use a little trick.
Since react takes care of all the visual state of the application we just have to make sure that after our async function completes it should somehow tell redux that "yo! buddy I have done the thing that you asked for" and then redux can simply add/modify that information inside the global state tree.

And here is how we can do that.

Loading Async Data in reducer

This is a multi-step process

  1. First we will pass an action to the reducer which will make an async call.
  2. Then on the callback of that async action we will set up another dispatch that will be called after that async action completes.
  3. In the meanwhile we can return that state of the tree with an isLoading label set to true from the original action.
  4. The on-completion action will just return the state with the modified values and the loading label to false.

et voila.

Example Application.

Example Application Screenshot

In this application, I have used the same concept to load users asynchronously from jsonplaceholder. api.

You can check out the Github repo from here 👇

REDUX for async tasks

You can manage async data in redux via two methods

  1. Via 3rd party liberary like redux thunk
  2. Unhealthy but simple way : Kind of a ruse

I am not using the second way because it adds additional compelexiy of the middle ware.

Main concept behind 2nd method

Since state of the application changes everytime the state tree changes. I can dispatch onCompletion action in the callbackasyncLoading action which is inside the reducer.

const reducer = (state = initialState, action) => {
    let { users } = state;
    if (action.type === DONE) {
        console.log('-updated-')
        return { ...state, loading: false}
    } else if (action.type === LOAD_USER) {
        loadUser(...).then((user) => {
            users.push(user)
…
Enter fullscreen mode Exit fullscreen mode

Live Demo

Thanks for reading.
Hope this may have added a little value, however small that may be.

Resources

Cover Image:
https://medium.com/swlh/handling-asynchronous-actions-with-redux-thunk-86b8d8e0b83e

This article by Robin Kim follows the redux-thunk middleware approach so it's my advice to check it out.

Thanks again! Have a lovely day.

💖 💪 🙅 🚩
icecoffee
Atulit Anand

Posted on August 12, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related