You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 07:54:53