为什么中止的 thunk 没有立即被拒绝,我该如何处理加载

Why an aborted thunk is not rejected imediatly, how can i handle loading

我正在尝试使用 ReduxToolkit 构建一个简单的用例:

我用了一个效果:

  useEffect(() => {
    const runningThunk = dispatch(asyncThunk());
    return () => {
      runningThunk.abort();
    };
  }, [dispatch, count]);

和一个基本切片:

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;
    });

当我 运行 这段代码时,将调用中止,然后重新 运行 挂钩并调用新的分派。到目前为止一切顺利。

但是redux的处理方式不一样。 在拒绝前一个 thunk 之前,将调度第二个 thunk 并调度未决操作。

1 - async-thunk/pending (Call 1)
2 - async-thunk/pending (Call 2)
3 - async-thunk/rejected (Call 1)
4 - async-thunk/fulfilled (Call 2)

这导致我的加载指示器仅在第 1 步和第 3 步之间显示,因为被拒绝的 thunk 重置了状态。

这是一个错误吗?如果这是想要的行为,我该如何处理我的问题?

当我们在 thunk 结束前两次更改计数器时重现问题的沙箱。

https://codesandbox.io/s/wonderful-chaum-stgsn

这是不可避免的。 运行 thunk 是异步的,中止它也是异步的。 不过启动 thunk 是同步发生的。

如果您有这样的顾虑,您应该跟踪您商店中最近启动的 thunk 的 requestId,并且仅在与此 requestId 相关的操作出现时更新您的商店。

参见 createAsyncThunk api documentation

上的第一个示例