【发布时间】:2022-08-17 10:18:13
【问题描述】:
我尝试在使用 apollo 客户端的反应应用程序中实现缓存分页。
我的查询有 filter 参数,它应该是在缓存对象中创建新键的唯一参数。
由于某种原因,当 fetchMore 发生指定过滤器时,新数据不会导致组件中的重新渲染。
我在合并函数中记录了现有参数和传入参数,似乎对于每个具有过滤器的 fetchMore,新数据确实到达了。所以,我不明白为什么组件没有重新渲染。
让事情变得更糟:在有或没有过滤器的情况下多次调用 fetchMore 发送 http 请求并将传入数据与现有数据合并。我希望不会发生这种情况,因为客户端应该看到它在缓存中已经有一个带有该键参数的查询的键。
以下是查询:
query Shells($first: Int = 5, $offset: Int = 0, $filter: ShellFilter) {
shells(
orderBy: [STATUS_ASC, EXECUTION_FROM_DESC]
first: $first
offset: $offset
filter: $filter
) {
nodes {
...ShellData
}
totalCount
}
}
apolloClient 配置是这样的:
const client = new ApolloClient({
cache: new InMemoryCache({
typePolicies: {
Query: {
fields: {
shells: {
keyArgs: [\'filter\'],
merge: (existing, incoming) => {
console.log(\'existing:\', existing, \'incoming:\', incoming);
return mergeObjectsAndNestedArrays<ShellsConnection>(
existing,
incoming,
\'nodes\',
);
},
},
},
},
},
})
以及显示它的组件:
const ControlCenter = () => {
const { showModal } = useModalContext();
const [page, setPage] = useState(1);
const { data, loading, fetchMore } = useShellsQuery();
const [query, setQuery] = useURLQuery();
const onCounterpartiesChange = async (counterparties) => {
await fetchMore({
variables: {
filter: { shellCounterParties: { some: { orgId: { in: \'20584\' } } } },
},
});
setQuery({ counterparties });
};
const shells = data?.shells?.nodes;
console.log(\'hello from shells:\', shells);
这些是日志:
-
更新 useEffect 中的状态。然后它将触发渲染。
-
似乎是一个补丁。 fetchMore 没有过滤器 arg,重新渲染了没有 useEffect 的组件。
-
以防万一,您是否确保
mergeObjectsAndNestedArrays返回数据的确切形状?另外,最好使用apollo devtools 检查 apollo 缓存数据
标签: reactjs caching graphql apollo-client