Blog>
Snippets

Concurrent Requests with createAsyncThunk

Illustrate the dispatch of concurrent network requests using createAsyncThunk and managing their states individually within the application.
import { createAsyncThunk, createSlice } from '@reduxjs/toolkit';

// Define the first async thunk
export const fetchUserById = createAsyncThunk(
  'users/fetchByIdStatus',
  async (userId, thunkAPI) => {
    const response = await fetch(`https://api.example.com/users/${userId}`);
    return response.json();
  }
);

// Define the second async thunk
export const fetchProjectById = createAsyncThunk(
  'projects/fetchByIdStatus',
  async (projectId, thunkAPI) => {
    const response = await fetch(`https://api.example.com/projects/${projectId}`);
    return response.json();
  }
);
Defines two createAsyncThunk actions for fetching a user and a project by their respective ID's.
const initialState = {
  user: null,
  project: null,
  loading: false,
  error: null
};

// Create a slice including reducers for handling the actions
const exampleSlice = createSlice({
  name: 'example',
  initialState,
  reducers: {},
  extraReducers: {
    [fetchUserById.pending]: (state) => {
      state.loading = true;
      state.error = null;
    },
    [fetchUserById.fulfilled]: (state, action) => {
      state.loading = false;
      state.user = action.payload;
    },
    [fetchUserById.rejected]: (state, action) => {
      state.loading = false;
      state.error = action.error;
    },
    [fetchProjectById.pending]: (state) => {
      state.loading = true;
      state.error = null;
    },
    [fetchProjectById.fulfilled]: (state, action) => {
      state.loading = false;
      state.project = action.payload;
    },
    [fetchProjectById.rejected]: (state, action) => {
      state.loading = false;
      state.error = action.error;
    }
  }
});

export const exampleReducer = exampleSlice.reducer;
Defines a Redux slice with a reducer to manage the state changes for both async thunks.
import { useDispatch } from 'react-redux';

// Dispatch the thunks concurrently
function loadData(userId, projectId) {
  const dispatch = useDispatch();

  useEffect(() => {
    // Dispatch both thunks at the same time
    dispatch(fetchUserById(userId));
    dispatch(fetchProjectById(projectId));
  }, [dispatch, userId, projectId]);
}
Uses a React hook to dispatch both thunks concurrently when component loads or IDs change.