突变后如何使 Relay 的缓存失效

How to invalidate Relay's cache after mutation

我正在使用 React/Relay/GraphQL 重建一个小型内部网络应用程序以熟悉此堆栈。基本上,它监控 "active" 视频列表的分析。唯一的变化是用新列表替换活动视频 ID 列表。 问题是在替换 ID 后,Relay 继续传送旧的 ID 列表而不是新的。

我一直无法弄清楚如何操作传递给 commitMutation()updateroptimisticUpdater 回调的商店。我只需要清除存储的活动视频列表,这样它就知道调用一个新视频,或者让它重新运行 graphql 查询以刷新缓存。

具体来说,我需要清除此查询的结果:

const ActiveVideosQuery = graphql`
    query App_ActiveVideos_Query {
        activeVideos {
            ...SetActiveVideosPage_activeVideos
            ...VideoList_activeVideos
        }
    }
`

突变(TypeScript):

const { commitMutation, graphql } = require('react-relay')


const mutation = graphql`
    mutation SetActiveVideosMutation($input: SetActiveVideosInput!) {
        setActiveVideos(input: $input) {
            clientMutationId
        }
    }
`

let nextClientMutationId = 0

function commit(environment, ids: string[]) {
    const clientMutationId = nextClientMutationId++

    return commitMutation(environment, {
        mutation,
        variables: { input: { ids, clientMutationId } },
    })
}


export default { commit }

架构:

type Channel {
  id: ID!
  name: String!
}

type Mutation {
  setActiveVideos(input: SetActiveVideosInput!): SetActiveVideosPayload
}

type Query {
  activeVideos: [Video]!
}

input SetActiveVideosInput {
  ids: [ID]!
  clientMutationId: String!
}

type SetActiveVideosPayload {
  clientMutationId: String!
}

type Video {
  id: ID!
  active: Boolean!
  details: VideoDetails
  statsByAge(seconds: Int!): [VideoStats]!
}

type VideoDetails {
  title: String!
  description: String!
  thumbnailURL: String!
  publishedAt: String!
  channel: Channel!
}

type VideoStats {
  videoID: ID!
  recordedAt: String!
  views: String!
  likes: String!
  dislikes: String!
  favorites: String!
  comments: String!
}

您将要使用 The Relay "Environment"

The Relay "Environment" bundles together the configuration, cache storage, and network-handling that Relay needs in order to operate.

Question为什么没有命令 Relay.reset() 可以简单地从应用程序中擦除所有内容?

Answer: 因为只实例化一个新的 Relay.Environment() 而不是试图确保你已经清理了全局单例上的所有东西[=36] =].

编辑:回应您的评论;

Relay currently offers very coarse-grained control of when data is refetched: primeCache defaults to fulfilling queries using in-memory data, while forceFetch bypasses the cache and refetches data in-full from the server. Again, in practice this has worked well for most of our use cases.


重新获取和缓存逐出控制view issue

Regarding cache eviction, it's import to understand that Relay is fundamentally different from many typical caches. Whereas typical caches store independent key/value pairs, Relay caches a graph of interconnected objects. We cover the ramifications of this extensively in Thinking in GraphQL. In practice, this means that simple approaches to cache eviction such as TTL or LRU may have unintuitive consequences. For example, products typically care about queries while the cache stores normalized records. If even a single record is evicted from the cache, it could cause an entire query to be effectively "missing" and need to be refetched. Further, the data dependencies of discrete parts of the application may overlap, such that they disagree about the allowable staleness of data.