I just started using Redux Toolkit(RTK), and I'm having a hard time figuring out a proper way of using createAsyncThunk from RTK.
So what I'm trying to do is to
- dispatch an asynchronous action created by
createAsyncThunk - update store with fetched data,
- and dispatch another synchronous action within a same payload creator.
For example, you could write such code with redux-saga like below.
function* fetchBooksSaga() {
try {
yield put(fetchBooksStart()); // set loading
const keyword = yield select(state => state.keyword); // get keyword from store
const { data } = yield call(SearchBooksAPI, query); // fetch books
yield put(fetchBooksSuccess(data)); // set books
// Here, you can dispatch another action with newly updated state.
const books = yield select(state => state.books);
// I know you can just use 'data' variable here,
// but let's say you have to update store first.
yield put(anotherAction(books));
} catch (error) {
yield put(fetchBooksFailure(error)); // set error
}
}
I was trying to write same code with createAsyncThunk, and the result looks like below.
export const fetchBooks = createAsyncThunk(
'BOOKS/FETCH_BOOKS',
async (params, ThunkAPI) => {
try {
// when 'fetchBooks' is dispatched, fetchBooks.pending will be dispatched automatically.
const { keyword } = ThunkAPI.getState(); // get keyword from store.
const { data } = await SearchBooksAPI(query); // fetch books
ThunkAPI.dispatch(fetchBooks.fulfilled(data)); // set books
// store updated at this moment
const { books } = ThunkAPI.getState();
ThunkAPI.dispatch(anotherAction(books));
// NOPE - returning value here will dispatch fetchBooks.fulfilled again.
return data;
} catch (error) {
ThunkAPI.rejectWithValue(error); // dispatch fetchBooks.rejected
}
}
);
Like its name, payload creator should create a payload. So it's obvious that I should return something within a payload creator. But in this case, returning value will dispatch asyncAction.fulfilled again, with returned value wrapped by Promise as payload.
I could just use a normal thunk action or saga, but the reason I'm trying this way is to minimize boilerplate. Using a normal thunk action will require to create action creators for pending/success/failure, which is not necessary when using createAsyncThunk.
Does anyone have idea that could help me solve this issue? any comments will be appreciated. Thank you for reading.