为什么我下面的示例可以在 fetchPolicy“仅网络”下正常工作,但在“缓存优先”下却不能正常工作?
我正在使用 React、apollo-client 和“relay”风格的基于光标的分页。 pageSize = 50,总共有64个项目。这是我的现场政策:
const typePolicies: TypedTypePolicies = {
Query: {
fields: {
allRetailers: customRelayStylePagination(['filter'])
}
}
}
customRelayStylePagination 只是从 relayStylePagination 复制粘贴来调试。
这是我检索所有零售商的功能:
const getAllRetailers = async (showInactiveRetailers: boolean, showInactiveMachines: boolean): Promise<Array<RetailerListItemFragment>> => {
let myCursor = undefined;
let hasNextPage = true;
let result: Array<RetailerListItemFragment> = [];
const filter = showInactiveRetailers
? undefined
: {
machineFilter: showInactiveMachines
? RetailerMachineFilter.HasActiveOrInactiveMachines
: RetailerMachineFilter.HasActiveMachines,
};
try {
console.log('start');
while(hasNextPage) {
const res: ApolloQueryResult<GetRetailerListQuery> = await apolloClient.query<
GetRetailerListQuery,
GetRetailerListQueryVariables
>({
variables: {
cursor: myCursor,
filter
},
query: GET_RETAILER_LIST,
fetchPolicy: 'cache-first'
});
myCursor = res.data.allRetailers?.pageInfo.endCursor;
hasNextPage = res.data.allRetailers?.pageInfo.hasNextPage || false;
console.log('hasNext: ' + hasNextPage);
result = res.data.allRetailers?.edges?.map(c => c.node) || [];
}
console.log('done', result);
return result;
} catch(err) {
console.error(err);
throw err;
}
}
如上所述,这对于“网络”来说效果很好,但在使用“缓存优先”时则不然。我陷入了无限循环,其中 hasNextPage 始终为 true。第一个 GraphQL 请求返回 50 个项目。我认为第二个也返回 50 项。我观察到两个 read() 都包含 50 个项目。
我在这里做错了什么?
我认为会发生以下情况:
cache-first
获取策略意味着 Apollo 在向 GraphQL 服务器进行查询之前将首先查看其缓存。如果它认为所有元素都存在于缓存中,那么它不会向服务器发出请求。relayStylePagination()
时,keyArgs
设置为 false。在您的代码中,您将其设置为过滤器,但这对于 Apollo 来说都是一样的:在这两种情况下,它都会忽略您的光标变量不同的事实。因此,它会认为所有元素都存在于缓存中,不需要向服务器发出请求。我在这方面浪费了几个小时,我的理解是
relayStylePagination()
根本无法使用缓存优先获取策略。