Blog>
Snippets

Defining ExtraReducers with the Builder Callback Pattern

Show a code example of how to define extraReducers using the builder callback pattern in a createSlice function, handling asynchronous actions from createAsyncThunk.
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';

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

// Slice definition with extraReducers
const userSlice = createSlice({
  name: 'user',
  initialState: {
    data: null,
    status: 'idle',
    error: null
  },
  reducers: {
    // standard reducer logic
  },
  extraReducers: (builder) => {
    builder
      .addCase(fetchUserData.pending, (state) => {
        state.status = 'loading';
      })
      .addCase(fetchUserData.fulfilled, (state, action) => {
        state.status = 'succeeded';
        state.data = action.payload;
      })
      .addCase(fetchUserData.rejected, (state, action) => {
        state.status = 'failed';
        state.error = action.error.message;
      });
  }
});

export default userSlice.reducer;
This code defines a 'user' slice with an initial state. It uses createAsyncThunk to define an asynchronous action called 'fetchUserData'. This action is meant to fetch user data from an API and return it as a payload. The 'extraReducers' field is used with the builder callback pattern to add cases for handling the pending, fulfilled, and rejected states of the 'fetchUserData' action, thereby updating the slice's state accordingly.