如何在Apollo Client的useMutation中无需重新获取即可更新多个查询?
直接更新Apollo Client缓存替代重查询的实现方案
你可以在update函数里扩展逻辑,直接操作缓存来更新ALL_AUTHORS和ALL_GENRES的数据,不用再依赖refetchQueries。具体实现要根据你的查询结构调整,下面是常见场景的示例:
1. 更新ALL_AUTHORS缓存
假设ALL_AUTHORS返回的是包含作者信息(比如name、booksCount)的数组,新增书籍后需要对应作者的书籍数+1,或者把新书关联到该作者的书籍列表中:
const [addBook] = useMutation(ADD_BOOK, { update: (cache, response) => { const newBook = response.data.addBook; // 保留原有更新ALL_BOOKS的逻辑 cache.updateQuery({ query: ALL_BOOKS }, ({ allBooks }) => { return { allBooks: allBooks.concat(newBook) }; }); // 更新ALL_AUTHORS缓存 cache.updateQuery({ query: ALL_AUTHORS }, ({ allAuthors }) => { if (!allAuthors) return { allAuthors: [] }; // 找到新书对应的作者,更新其书籍数或书籍列表 const updatedAuthors = allAuthors.map(author => { if (author.name === newBook.author.name) { return { ...author, booksCount: author.booksCount + 1, // 若有该字段则更新 // 若作者有books列表,可追加新书: // books: [...author.books, newBook] }; } return author; }); return { allAuthors: updatedAuthors }; }); }, // 移除原refetchQueries相关配置 });
2. 更新ALL_GENRES缓存
如果ALL_GENRES返回的是所有已存在的genre列表,新书的genre可能是新增的,需要去重后加入列表:
// 在同一个update函数内继续添加以下逻辑: // 更新ALL_GENRES缓存 cache.updateQuery({ query: ALL_GENRES }, ({ allGenres }) => { if (!allGenres) return { allGenres: [] }; const newGenre = newBook.genre; // 检查genre是否已存在,不存在则添加 if (!allGenres.includes(newGenre)) { return { allGenres: [...allGenres, newGenre] }; } // 已存在则返回原数据 return { allGenres }; });
额外提示
- 如果查询带变量(比如带筛选条件的
ALL_AUTHORS),需要在updateQuery参数里加上对应的variables,确保更新的是正确的缓存条目。 - 若缓存结构复杂(比如嵌套关联),可以用
cache.modify更灵活地操作实体,比如通过ID关联作者和书籍,避免靠名字匹配:cache.modify({ id: cache.identify(newBook.author), // 获取作者的缓存ID fields: { booksCount(prev) { return prev + 1; } } });
内容的提问来源于stack exchange,提问作者theori
相关产品推荐
相关产品推荐

