graphql-codegen配合typescript-svelte-apollo生成查询的refetch功能失效如何解决
问题根源
- 类型报错原因:
graphql-codegen-svelte-apollo生成的查询返回的Svelte store中,refetch方法没有直接挂载在store返回值上,而是挂载在内部的query(即Apollo的ObservableQuery实例)属性下,直接调用$observations.refetch自然会提示属性不存在。 - 响应式更新filter未触发重新查询的原因:你的Apollo Client配置中,
observations字段使用了relayStylePagination但未指定keyArgs,Apollo会将所有携带不同filter参数的查询都视为同一个字段的缓存,优先读取旧缓存而不是发起新请求。
解决方法
方案1:使用正确的refetch/setVariables调用(推荐,性能更好)
不需要每次filter变化都重建查询实例,复用同一个实例调用更新方法即可,修改你的Svelte代码:
<script lang="ts"> import { getObservations } from '$lib/generated'; // 仅初始化一次查询实例 const observations = getObservations({ variables: { filter }, // 可选:指定fetchPolicy确保数据新鲜,可选值 network-only / cache-and-network fetchPolicy: 'cache-and-network' }); function handleFilter(event) { const newFilter = event.detail; // 写法1:调用refetch传入新变量 $observations.query.refetch({ filter: newFilter }); // 写法2:更轻量的setVariables,自动触发重新查询 // $observations.query.setVariables({ filter: newFilter }); } </script> <!-- 模板部分保持不变 --> {#if $observations.loading} 加载中... {:else if $observations.error} {$observations.error} {:else if $observations.data} {#each $observations.data.observations.edges as edge} <Item node={edge.node} /> {/each} {/if}
该写法不会产生类型错误,因为$observations.query本身就是标准的Apollo ObservableQuery实例,原生支持refetch、setVariables等方法。
方案2:保留响应式声明自动触发查询
如果你希望保持$: observations = getObservations({ variables: { filter } })的响应式写法,只需要修改Apollo Client的缓存配置,给relayStylePagination添加keyArgs,明确用filter参数区分不同的缓存条目:
export default new ApolloClient({ link: authLink.concat(httpLink), cache: new InMemoryCache({ typePolicies: { Query: { fields: { // 把filter作为缓存区分的key,如果有其他筛选/分页参数也一并加入数组 observations: relayStylePagination(['filter']), }, }, }, }) });
修改后filter变化时会自动触发新的查询,无需手动调用更新方法。
内容的提问来源于stack exchange,提问作者nimmolo
相关产品推荐
相关产品推荐

