reduxfrontendredux-toolkitredux-thunk

Redux Toolkit AsyncThunk dispatch


Can I access dispatch inside extraReducers? I want to dispatch action based of the asyncThunk function, if it failed or completed.

const todosSlice = createSlice({
    name: "todos",
    initialState,
    reducers: {},
    extraReducers: (builder) => {
        console.log(builder);
        builder.addCase(fetchTodos.pending, (state) => {
            return { ...state, isFetching: true };
        });
        builder.addCase(fetchTodos.fulfilled, (state, action) => {
            return { ...state, isFetching: false, data: action.payload.data };
        });
        builder.addCase(fetchTodos.rejected, (state, action) => {
            console.log("Can console here if reject occurs");
            return { ...state, isFetching: false, error: action.error };
        });
    },
});

export const todosSliceState = (state) => state.todos;

export default todosSlice.reducer;

So i want to dispath action inside fetchTodos.fulfilled and that action will just shange state of other reduxSlice


Solution

  • Can I access dispatch inside extraReducers? I want to dispatch action based of the asyncThunk function, if it failed or completed.

    No, since reducers are pure functions, they can't have side-effects like dispatching other actions.

    Just add fetchTodos.fulfilled as a reducer case in the other slice/reducer that has the state you would like to update.

    Alternatively you could also dispatch actions from the fetchTodos action, which are handled in other reducers, based on the success/failure of some asynchronous logic.

    Example:

    const fetchTodos = createAsyncThunk(
      "fetchTodos",
      async (arg, thunkApi) => {
        try {
          ... asynchronous fetch logic
          thunkApi.dispatch(someAction(somePayload));           // <-- success
          return someValue;
        } catch(error) {
          thunkApi.dispatch(someOtherAction(someOtherPayload)); // <-- failure
          return thunkApi.rejectWithValue(error);
        }
      }
    );