Skip to main content

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.