I'm trying to build a simple use case with ReduxToolkit :
I use an effect :
useEffect(() => {
const runningThunk = dispatch(asyncThunk());
return () => {
runningThunk.abort();
};
}, [dispatch, count]);
and a basic slice :
extraReducers: (builder) => {
builder.addCase(asyncThunk.pending, (state) => {
state.isLoading = true;
});
builder.addCase(asyncThunk.fulfilled, (state) => {
state.isLoading = false;
});
builder.addCase(asyncThunk.rejected, (state) => {
state.isLoading = false;
});
When i run this code, the abort is called then the hook is re-runned and a new dispatch is called. So far so good.
But redux does not handle it the same way. The 2nd thunk is dispatched and the pending action is dispatched BEFORE the previous thunk is rejected.
1 - async-thunk/pending (Call 1)
2 - async-thunk/pending (Call 2)
3 - async-thunk/rejected (Call 1)
4 - async-thunk/fulfilled (Call 2)
This result in my loading indicator only displayed between step 1 and step 3 since the rejected thunk reset the state.
Is that a bug ? If this is the wanted behavior, how can i handle my problem ?
A sandbox reproducing the issue when we change the counter twice before the thunk ends.
It is not avoidable. A running thunk is asynchronous, and aborting it is asynchronous as well. Starting a thunk happens synchronously though.
If you have concerns like this, you should track the requestId
of the most recently started thunk in your store and only update your store when an action with this requestId
comes along.
See the first example on the createAsyncThunk api documentation