DEV Community

Coder
Coder

Posted on

React + Redux Toolkit - Fetch Data in Async Action with createAsyncThunk

If you have worked with React and Redux before, you know that handling asynchronous actions can be a little tricky. Redux Toolkit provides an easy solution to this problem with its createAsyncThunk function.

In this blog post, we will cover how to fetch data in an async action using createAsyncThunk with React and Redux Toolkit.

What is Redux Toolkit?

Redux Toolkit is a package created by the Redux team to make working with Redux easier and more efficient. It includes a set of opinionated tools and utilities that make common Redux use cases much simpler, such as store setup, defining reducers, and creating actions.

Here are some of the features that Redux Toolkit provides:

  • Provides a simplified way to write Redux logic with less boilerplate
  • Includes a configureStore() function with sane defaults and good defaults for production code
  • Provides utilities to generate action types and action creators
  • Includes a powerful createAsyncThunk function that makes handling async logic much simpler

What is createAsyncThunk?

createAsyncThunk is a function provided by Redux Toolkit that makes it easy to handle async logic in your Redux actions.

With createAsyncThunk, you can define an async action that will automatically dispatch the three Redux actions needed to handle async operations: pending, fulfilled, and rejected.

createAsyncThunk also provides some additional options that allow you to customize the behavior of your async action, such as defining how many times it should retry if it fails.

How to Use createAsyncThunk

Here is an example of how to use createAsyncThunk to fetch data from an API:

import { createAsyncThunk } from '@reduxjs/toolkit';
import { fetchData } from 'api';

export const fetchUserData = createAsyncThunk(
  'user/fetchUserData',
  async () => {
    const response = await fetchData('/user');
    return response.data;
  }
);
Enter fullscreen mode Exit fullscreen mode

In this example, we first import createAsyncThunk from @reduxjs/toolkit. We also import an API function called fetchData that returns a Promise that resolves to the data we want to fetch.

We then define an async action called fetchUserData using createAsyncThunk. This action will dispatch a pending action with the type user/fetchUserData/pending when it is first invoked.

It will then call the function passed as the second argument to createAsyncThunk, which in this case is an async function that fetches the data from the API. When the Promise returned by this function resolves, it will dispatch a fulfilled action with the type user/fetchUserData/fulfilled and pass the data as its payload.

If the Promise returned by the function passed to createAsyncThunk rejects, it will dispatch a rejected action with the type user/fetchUserData/rejected and pass the error as its payload.

How to Use createAsyncThunk with a Loading State

In some cases, you may want to display a loading spinner or message while your async action is pending. To do this, you can create a loading state in your Redux store and update it in the pending action handler.

Here is an example of how to do this:

import { createSlice } from '@reduxjs/toolkit';
import { fetchUserData } from './actions';

const initialState = {
  data: null,
  isLoading: false,
  error: null
};

const userSlice = createSlice({
  name: 'user',
  initialState,
  reducers: {},
  extraReducers: builder => {
    builder
      .addCase(fetchUserData.pending, state => {
        state.isLoading = true;
      })
      .addCase(fetchUserData.fulfilled, (state, action) => {
        state.isLoading = false;
        state.data = action.payload;
      })
      .addCase(fetchUserData.rejected, (state, action) => {
        state.isLoading = false;
        state.error = action.payload;
      });
  }
});
Enter fullscreen mode Exit fullscreen mode

In this example, we define a isLoading property in our initial state with a value of false. We also define three extra reducers using builder, one for each of the three actions dispatched by our fetchUserData async action.

In the pending action handler, we set isLoading to true.

In the fulfilled action handler, we set isLoading back to false and update our data property with the data returned by the API.

In the rejected action handler, we set isLoading back to false and update our error property with the error returned by the API.

Conclusion

In this blog post, we covered how to use createAsyncThunk to fetch data in an async action using React and Redux Toolkit. We also covered how to use a loading state to display a loading spinner or message while our async action is pending.

Redux Toolkit is a powerful tool that can make working with Redux much simpler and more efficient. If you haven't already, I encourage you to give it a try in your next React project.

Top comments (0)