Search code examples
reactjstypescriptreduxredux-thunkredux-toolkit

Redux toolkit thunk wait for state change


I am using redux toolkit with thunk to receive data from api.
I need to fetch data from 2 apis in consecutive order using data I got from the first api call as a argument of second api call (search1 first, then search2)
In order to do that, I need to wait for the first dispatch to fully complete its job from calling getSearch1 to updating the state.

Please help!

// store
import { configureStore } from "@reduxjs/toolkit";
import searchReducer from "./slice/searchSlice";

export const store = configureStore({
  reducer: {
    search: searchReducer,
  },
});

export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;
export default store;
// slice
export const getSearch1 = createAsyncThunk(
  "search/getSearch1",
  async (args: string[]) => {
    const result = await ApiUtil.search1(args);
    return result;
  }
);

export const getSearch2 = createAsyncThunk(
  "search/getSearch2",
  async (ids: string[]) => {
    const result = await ApiUtil.search2(ids);
    return result;
  }
);

export const searchSlice = createSlice({
  name: "search",
  initialState,
  reducers: {...},
  extraReducers: (builder) => {
    builder
      .addCase(getSearch1.fulfilled, (state, action) => {
        state.search1 = action.payload;
      })
      .addCase(getSearch2.fulfilled, (state, action) => {
        state.search2 = action.payload;
      });
  },
});
// home page
import {
  ...
  getSearch1,
  getSearch2,
} from "../../redux/slice/searchSlice";

  const handleSearch = () => {
    dispatch(getSearch1(args));
    const ids = search1?.map((item) => item.id.toString());
    dispatch(getSearch2(ids ?? []));
    history.push(ROUTES.RESULT_PAGE, search1);
  };

Solution

  • You can use .unwrap() method to achieve that,see the documentation :

      try {
        const { data } = await dispatch(getSearch1(args)).unwrap()
        await dispatch(getSearch2(data ?? []));
        // handle result here
      } catch (rejectedValueOrSerializedError) {
        // handle error here
      }