RTK Query invalidatesTags 似乎不会每次都删除缓存的数据

Posted

技术标签:

【中文标题】RTK Query invalidatesTags 似乎不会每次都删除缓存的数据【英文标题】:RTK Query invalidatesTags doesn't seem to remove cached data every time 【发布时间】:2022-01-13 08:45:37 【问题描述】:

我有一个 RTK 查询突变端点拒绝应用程序,它使 getApplication 查询无效。它们在同一个 API 中。

rejectApplication: builder.mutation<RejectResponse, string>(
  query: (applicationId) => (
    url: `/applications/$applicationId`,
    method: "DELETE",
  ),
  invalidatesTags: (_result, _error, applicationId) => [
    "Status",
     type: "Application", id: "LIST" ,
     type: "Application", id: applicationId ,
  ],
),
getApplication: builder.query<ApplicationResponse, string>(
  query: (applicationId: string) => (
    method: "GET",
    url: `/applications/$applicationId`,
  ),
  providesTags: (_result, _error, id) => [ type: "Application", id: id ],
),

问题是我有两个使用 useRejectApplicationMutation 挂钩的组件,但由于某种原因,其中只有一个似乎在查询结果失效后正确地从缓存中删除。我可以通过 Redux devtools 观察到这一点,在其中我可以看到在一个组件中完成拒绝突变后调度 removeQueryResult 操作,但在另一个组件中没有触发。这会导致组件中的getApplication数据没有变化,从而打断了应用的流程。

const 
  data,
  isLoading: getApplicationIsLoading,
  isError: getApplicationIsError,
 = useGetApplicationQuery(props.application.applicationId as string);

useEffect(() => 
  if (data) 
    dispatch(setIncompleteApplication(data));
  
, [data]);

因此,在这种情况下,不会调用带有数据的 useEffect,因为似乎没有重新获取数据,尽管它应该在满足拒绝突变后失效。奇怪的是,在控制台中,它看起来确实应该正确地重新获取无效的应用程序和状态,因为 MSW 端点在删除请求之后被命中。

[MSW] 12:37:38 DELETE /v1/applications/XA1234567 (200 OK)
[MSW] 12:37:38 GET /v1/status (200 OK) 
[MSW] 12:37:39 GET /v1/applications/XA1234567 (200 OK)

对我来说,问题似乎是由于某种原因没有正确清除缓存,因此尽管标签无效并且重新获取导致数据未正确重置。有什么想法可能导致这种不一致吗?

【问题讨论】:

【参考方案1】:

invalidatesTags 并不总是从缓存中删除内容。它仅从缓存中删除当前未在组件中使用的缓存条目的内容-对于触发重新获取的所有其他内容,因此再次触发请求,如果响应中有新数据,则更新响应相应地。

所以在您的组件中,isFetching 将切换到 true,但数据不会消失 - 在大多数情况下,这是首选行为,因为您不希望所有内容都跳转到加载指示器,而只是在突变后更新显示的数据。

现在,如果您的端点返回的数据在结构上与之前返回的数据相同,那么它也不会是新的 data 对象,而只是旧对象。在重新获取时,RTK-Query 会比较新旧结果,并尝试尽可能多地保持引用相等,因此当基础数据实际上根本没有改变时,useEffects 不会被触发。

【讨论】:

我明白了,有道理。感谢您的快速回复。

以上是关于RTK Query invalidatesTags 似乎不会每次都删除缓存的数据的主要内容,如果未能解决你的问题,请参考以下文章

Redux Toolkit RTK Query 发送查询参数

RTK Query 使用 getState() 从另一个切片获取状态

@mswjs/data 问题:为啥 RTK-Query 沙箱示例需要单独手动编码 POST 和 PUT 模拟?

React Native & RTK Query - 请求成功时调用另一个端点

React Native & RTK Query - IsLoading on refetch 方法

有没有办法获取存储在 api slice [RTK Query] 中的所有响应?