createAsyncThunk and writing reducer login with redux-toolkit

Viewed 2284

I was reading createAsyncThunk documentation, and felt kind of confused with the flow. This is from the docs:

import { createAsyncThunk, createSlice } from '@reduxjs/toolkit'
import { userAPI } from './userAPI'

// First, create the thunk
const fetchUserById = createAsyncThunk(
  'users/fetchByIdStatus',
  async (userId, thunkAPI) => {
    const response = await userAPI.fetchById(userId)
    return response.data
  }
)

// Then, handle actions in your reducers:
const usersSlice = createSlice({
  name: 'users',
  initialState: { entities: [], loading: 'idle' },
  reducers: {
    // standard reducer logic, with auto-generated action types per reducer
  },
  extraReducers: {
    // Add reducers for additional action types here, and handle loading state as needed
    [fetchUserById.fulfilled]: (state, action) => {
      // Add user to the state array
      state.entities.push(action.payload)
    }
  }
})

// Later, dispatch the thunk as needed in the app
dispatch(fetchUserById(123))


What do I have to write in the reducers and extraReducers? Standard reducer logic?

I have this CodeSandbox that I implemented the old redux way. Now, need to implement redux-toolkit in it.

1 Answers

The reducers property of createSlice allows you to make an action creator function and respond to those actions in one step. You use extraReducers to respond to an action that has already been created elsewhere, like in an async thunk. The extraReducer just responds to an action but does not create an action creator function.

The example is saying that you can have some regular reducers in addition to the extraReducers. But I looked at your CodeSandbox and in your case you do not need any other reducers because the only actions that you are responding to are the three actions from the async thunk.

Since your createSlice isn't going to make any action creators you don't really need to use createSlice. You can use it, but you can also just use createReducer.

import { createAsyncThunk, createSlice } from '@reduxjs/toolkit'
import { userAPI } from './userAPI'

export const fetchUserFromGithub = createAsyncThunk(
  'users/fetch',
  async (username) => {
    const response = await axios.get(
      `https://api.github.com/users/${username}`
    );
    return response.data
  }
)

const usersSlice = createSlice({
  name: 'users',
  initialState: {
    user: null,
    fetchingUser: false,
    fetchingError: null
  },
  reducers: {},
  extraReducers: {
    [fetchUserFromGithub.pending]: (state, action) => {
      state.fetchingUser = true;
      state.fetchingError = null;
    },
    [fetchUserFromGithub.rejected]: (state, action) => {
      state.fetchingUser = false;
      state.fetchingError = action.error;
    }
    [fetchUserFromGithub.fulfilled]: (state, action) => {
      state.fetchingUser = false;
      state.user = action.payload;
    }
  }
})
Related