问题描述
我正在为大量复杂的数据实现一个非常高级的表(使用 React-Table)。我开始按照 Apollo 的指南实现基于偏移的分页,我也开始排序工作。我所坚持的是将其与服务器端过滤相结合。
我对 InMemoryCache
的定义如下所示 - 我正在查询字段 Targets
:
const cache = new InMemoryCache({
typePolicies: {
Query: {
fields: {
Targets: {
...offsetLimitPagination(),read(existing,{ args }): any {
if (args && args.limit !== undefined && args.offset !== undefined) {
return existing && existing.slice(args.offset,args.offset + args.limit);
}
},},});
const { networkStatus,error,data,fetchMore,refetch } = useQuery<GetTargetsQuery,GetTargetsQueryVariables>(GET_TARGETS,{
...
notifyOnNetworkStatusChange: true,variables: {
limit: tableState.pageSize,offset: tableState.pageNumber * tableState.pageSize,orderBy: tableState.orderBy,where: {
_and: [initialFilters,queryFilters],});
问题是,当我修改 queryFilters
并重新获取数据时,我在浏览器的“网络”选项卡中看到正确的数据,但我的组件仍然从缓存中读取旧数据。似乎 offsetLimitPagination
钩子并不是专门为合并过滤而设计的(?)。
我不能使用 React-Table 的内置过滤,因为它只对已查询的数据进行操作(在我的情况下,它是整个集合的一部分)。 如果设置了新的过滤器,我该如何修改我的 InMemoryCache
以覆盖缓存中的数据?或者是否有更好的方法来解决这个问题或提出更好的问题来完成这项工作?
解决方法
为了阐明 keyArgs
,您需要指定将一个缓存与另一个连接起来的键。
就您而言,您有变量 limit
、offset
、orderBy
和 where
。
所以在改变limit&offset的情况下,你不希望Apollo在limit&offset改变的时候创建单独的缓存。所以你把它排除在 keyArgs
之外。
您要查看的 keyArgs 是您对 orderBy
和 where
的更改。根据我的理解,新的 keyArgs
是您想要建立缓存的基础。因此,如果 orderBy 和 where 中的任何内容发生变化,您都希望 Apollo 将其视为某种独立的数据集。
另外,offsetLimitPagination
接受一个 keyArgs 属性。
因此,对于像变量 where
这样的嵌套变量,您可以在 keyArgs 中将其配置为嵌套值,以便 Apollo 了解这些值的内部是什么。
嵌套数组语法适用于前一个参数值(where)。
const cache = new InMemoryCache({
typePolicies: {
Query: {
fields: {
Targets: {
...offsetLimitPagination(["orderBy","where",["_and"]]),read(existing,{ args }): any {
if (args && args.limit !== undefined && args.offset !== undefined) {
return existing && existing.slice(args.offset,args.offset + args.limit);
}
},},});