创建估算模板时Apollo refetchQueries报错:未知查询fetchEstimateTemplate
问题:创建估算模板时refetchQueries报错,无法获取新创建实体
我用Formik实现估算模板的自动保存功能,handleSave代码如下:
const handleSave = useCallback( async ({ id, ...values }: EstimateTemplateFormState) => { if (id && props.estimateTemplateId) { // 更新逻辑 const params = { estimateTemplateId: id, ...values }; const { data } = await updateEstimateTemplate({ variables: { params }, refetchQueries: ['fetchEstimateTemplate'] }); } else { // 创建逻辑 const params = values; const { data } = await createEstimateTemplate({ variables: { params }, refetchQueries: ['fetchEstimateTemplate'] }); } }, [createEstimateTemplate, updateEstimateTemplate, props.estimateTemplateId] );
编辑模板时更新逻辑正常,但创建新模板时出现报错:
Unknown query named "fetchEstimateTemplate" requested in refetchQueries options.include array
我的GraphQL查询定义:
query fetchEstimateTemplate($id: ID!) { estimateTemplate(id: $id) { .........fields........ } }
推测是创建时实体尚未存在导致的,需要解决这个问题以获取新创建的估算模板实体。
解决方案
原因分析
创建新模板时,fetchEstimateTemplate查询必须传入id参数,但此时新实体刚生成,组件上下文中还没有该id,Apollo Client找不到匹配的缓存查询(也无法执行无参数的该查询),因此报错。而更新场景下,id已存在,fetchEstimateTemplate有对应的缓存查询可重新获取,所以逻辑正常。
解决方法
方法1:创建完成后手动执行查询
创建成功后从返回数据中提取新模板的id,手动调用fetchEstimateTemplate查询:
const { data: createData } = await createEstimateTemplate({ variables: { params }, // 移除原refetchQueries配置 }); // 获取新模板ID const newTemplateId = createData.createEstimateTemplate.id; // 手动执行查询获取完整实体 await fetchEstimateTemplate({ variables: { id: newTemplateId } });
方法2:给refetchQueries传入完整查询配置
保留refetchQueries,但传入查询对象而非名称,同时指定新创建的id作为参数(需提前导入fetchEstimateTemplate查询):
// 导入查询 import { fetchEstimateTemplate } from './your-queries-path'; // 修改创建逻辑中的refetchQueries const { data: createData } = await createEstimateTemplate({ variables: { params }, refetchQueries: [ { query: fetchEstimateTemplate, variables: { id: createData.createEstimateTemplate.id } } ] });
注:需确保createEstimateTemplate的mutation返回新实体的id字段。
方法3:用update函数手动更新缓存
如果页面通过列表查询展示模板,可在创建mutation的update函数中直接操作缓存,将新实体添加到列表缓存并写入单个实体缓存,无需重新发起查询:
await createEstimateTemplate({ variables: { params }, update: (cache, { data: { createEstimateTemplate } }) => { // 更新列表缓存(假设有fetchEstimateTemplates列表查询) const existingTemplates = cache.readQuery({ query: fetchEstimateTemplates }); cache.writeQuery({ query: fetchEstimateTemplates, data: { estimateTemplates: [...existingTemplates.estimateTemplates, createEstimateTemplate] } }); // 写入单个实体缓存,后续fetchEstimateTemplate可直接命中缓存 cache.writeQuery({ query: fetchEstimateTemplate, variables: { id: createEstimateTemplate.id }, data: { estimateTemplate: createEstimateTemplate } }); } });
内容的提问来源于stack exchange,提问作者Dan Rubio
相关产品推荐
相关产品推荐

