AsyncThunk
Content
AsyncThunks
as well as Slices
are stored together for better readability and remove need to have additional imports.
To demonstrate how to create and use it, I will be using some Orders
state and ordersApi
as example.
Creation
Creation of AsyncThunk
is the same as in original documentation with usage of typed state
and dispatch
, with your API call do the following:
export const takeOrder = createAppAsyncThunk("orders/take", async (id: string) => {
return await ordersApi.takeOrder(id);
});
Where "orders/take""
is name of your slice and name of your method.
Slice handlers
You can handle the result inline or as I like with functions, all together it looks like this:
export const takeOrder = createAppAsyncThunk("order/take", async (id: string) => {
return await ordersApi.takeOrder(id);
});
function rehydrate(state: OrderState, rehydrateParams: RehydrateAppAction) {
return newState(rehydrateParams.payload?.orders || state, {});
}
function orderActionPendingHandler(state: OrderState, params: ReturnType<typeof takeOrder.pending>) {
return newState(state, {isLoading: true, error: null});
}
function takeOrderFulfilledHandler(state: OrderState, params: ReturnType<typeof takeOrder.fulfilled>) {
return newState(state, {isLoading: false, error: null, order: params.payload});
}
function orderActionRejectedHandler(state: OrderState, params: ReturnType<typeof takeOrder.rejected>) {
return newState(state, {isLoading: false, error: params.error.message});
}
export const {reducer: OrderReducer} = createSlice({
name: "order",
initialState: OrdersInitialState,
extraReducers: (builder) => {
builder
.addCase(REHYDRATE, rehydrate)
.addCase(takeOrder.pending, orderActionPendingHandler)
.addCase(takeOrder.fulfilled, takeOrderFulfilledHandler)
.addCase(takeOrder.rejected, orderActionRejectedHandler);
},
});
Promise result handlers
To handle promise results in pages/components (i.e. show error toast, show error in input, show success toast etc.) we can handle it the following way:
const onTakeOrderPress = useCallback(() => {
handlePromiseResult(dispatch(takeOrder(orderId)), localization.common.orderHasBeenSuccessfullyTaken);
}, [dispatch, orderId]);
To check more about handlePromiseResult
read more here.