I am learning how to use createAsyncThunk. I have created a simple counter app. It has an add and an subtract button. On clicking those buttons, the counter value with increase or decrease accordingly.
Now I want to add two more buttons which on clicking should do the same increment and decrement but it should be delayed by one second.
I am able to achieve the same when I don't use redux toolkit. This StackBlitz has the code without toolkit
But I am not sure how to approach the same using redux toolkit. Can someone guide me how I should write my createAsyncThunk call and extraReducers to achieve the same?
This Stackblitz contains an example of what I had tried with toolkit
I am not sure how to proceed with my createAsyncThunk
call. I tried to dispatch the action inside the createAsync
callback, but it did not work.
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
export const asyncAdd = createAsyncThunk('asyncAdd', async (_, thunkAPI) => {
});
const counterSlice = createSlice({
name: 'counter',
initialState: {
count: 0,
hasError: false,
isLoading: false,
users: {},
todos: {},
},
reducers: {
add: (state, action) => {
state.count += action.payload;
},
sub: (state) => {
state.count -= 1;
},
},
extraReducers: {
[asyncAdd.pending]: (state, action) => {
state.hasError = false;
state.isLoading = true;
console.log('PENDING');
},
[asyncAdd.fulfilled]: (state, action) => {
state.hasError = false;
state.isLoading = false;
console.log('payload ' + action.payload);
state.count = action.payload;
console.log('FULILLED');
},
[asyncAdd.rejected]: (state, action) => {
state.hasError = true;
state.isLoading = false;
console.log('REJECTED');
},
},
});
export const { add, sub } = counterSlice.actions;
export default counterSlice.reducer;
createAsyncThunk
is designed to process some late action using promises
, you have to return either a promise
or a resolved promise value.
Use
builder
object inextraReducers
to create pending, rejected and fullfilled cases
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
//method one using inbuild await
export const asyncAdd = createAsyncThunk('aextraReducerssyncAdd', (count) => {
return new Promise((res) => { // return a promise that resolves after one second
setTimeout(res, 1000, count);
});
});
//method two using await
export const asyncAdd2 = createAsyncThunk('asyncAdd',async (count) => {
const res = await new Promise((res) => { // return a promise that resolves after one second
setTimeout(res, 1000, count);
});
return res;
});
const counterSlice = createSlice({
name: 'counter',
initialState: {
count: 0,
hasError: false,
isLoading: false,
users: {},
todos: {},
},
reducers: {
add: (state, action) => {
state.count += action.payload;
},
sub: (state) => {
state.count -= 1;
},
},
extraReducers(builder) { //use builer
builder.addCase(asyncAdd.fulfilled, function (state, { payload }) {
state.count += payload;
}).addCase(asyncAdd.pending,function (state) {
state.isLoading = true;
}).addCase(asyncAdd.rejected,function (state) {
state.hasError = true;
});
},
});
export const { add, sub } = counterSlice.actions;
export default counterSlice.reducer;
I have forked the stackblitz also