如何在Apollo/GraphQL的refetchQueries中传入多个查询?含deleteSong场景
在Apollo/GraphQL中给refetchQueries传入多个查询的方法
嘿,这个问题其实挺容易解决的——Apollo里的refetchQueries本身就支持传入多个查询,不管是通用场景还是你说的deleteSong mutation执行后都一样,我给你拆解一下具体用法:
基础逻辑:refetchQueries接受数组形式的查询
refetchQueries的核心是接受一个查询配置数组,每个数组元素有两种写法:
- 直接传入预定义的查询文档(比如你提前用
gql定义好的查询) - 传入一个包含
query(查询文档)和variables(查询参数)的对象(适合需要动态传参的查询)
举个简单的通用示例:
// 提前定义两个查询 const GET_ALL_SONGS = gql` query GetAllSongs { songs { id title duration } } `; const GET_USER_LIKED_SONGS = gql` query GetUserLikedSongs($userId: ID!) { userLikedSongs(userId: $userId) { id songId } } `; // 任意操作中传入多个查询 client.mutate({ mutation: SOME_OTHER_MUTATION, refetchQueries: [ GET_ALL_SONGS, // 无参数的查询直接传文档 { query: GET_USER_LIKED_SONGS, variables: { userId: 'user_123' } // 需要参数的用对象传参 } ] });
针对deleteSong mutation的具体实现
当你的deleteSong mutation执行完成后,只需要把需要刷新的关联查询(比如歌曲列表、歌手的歌曲列表等)放进refetchQueries数组里就行。这里给你一个用useMutation钩子的完整示例:
import { useMutation, gql } from '@apollo/client'; // 定义deleteSong mutation const DELETE_SONG = gql` mutation DeleteSong($songId: ID!) { deleteSong(songId: $songId) { id artistId } } `; // 定义需要重新获取的查询 const GET_SONG_LIST = gql` query GetSongList { songs { id title artist } } `; const GET_ARTIST_SONG_LIST = gql` query GetArtistSongList($artistId: ID!) { artist(artistId: $artistId) { id name songs { id title } } } `; function SongItem({ songId, artistId }) { const [deleteSong] = useMutation(DELETE_SONG, { // 传入多个需要刷新的查询 refetchQueries: [ GET_SONG_LIST, // 刷新全局歌曲列表 { query: GET_ARTIST_SONG_LIST, variables: { artistId } // 刷新当前歌手的歌曲列表,带上动态参数 } ], // 可选:你也可以搭配update函数手动更新缓存,再用refetchQueries兜底确保数据最新 update(cache, { data: { deleteSong } }) { // 手动从GET_SONG_LIST的缓存中移除已删除的歌曲 const { songs } = cache.readQuery({ query: GET_SONG_LIST }); cache.writeQuery({ query: GET_SONG_LIST, data: { songs: songs.filter(song => song.id !== deleteSong.id) } }); } }); return ( <button onClick={() => deleteSong({ variables: { songId } })}> 删除这首歌 </button> ); }
更灵活的动态写法
如果你需要根据deleteSong的返回结果来决定要刷新哪些查询,还可以给refetchQueries传入一个函数,它会接收mutation的返回数据作为参数,动态生成查询数组:
const [deleteSong] = useMutation(DELETE_SONG, { refetchQueries: ({ data }) => { // 从返回结果里拿到被删除歌曲的歌手ID,动态刷新对应查询 const targetArtistId = data.deleteSong.artistId; return [ GET_SONG_LIST, { query: GET_ARTIST_SONG_LIST, variables: { artistId: targetArtistId } } ]; } });
这样不管是固定的多个查询,还是动态生成的查询列表,都能轻松实现啦。
内容的提问来源于stack exchange,提问作者Taylor Austin
相关产品推荐
相关产品推荐

