0

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

  • 发送 thunk
  • 显示装载机指示器
  • 如果在最后一个 thunk 完成运行之前发生了某些事情,则中止 thunk

我使用一个效果:

  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

4

1 回答 1

0

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

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

请参阅createAsyncThunk api 文档中的第一个示例

于 2021-09-03T22:22:19.950 回答