【问题标题】:How to invalidate Relay's cache after mutation突变后如何使Relay的缓存失效
【发布时间】:2018-01-03 20:01:40
【问题描述】:

我正在使用 React/Relay/GraphQL 重建一个小型内部 Web 应用程序以熟悉此堆栈。基本上,它监控“活动”视频列表的分析。唯一的变化是将活动视频 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!
}

【问题讨论】:

    标签: javascript reactjs relayjs relay react-relay


    【解决方案1】:

    你会想要使用The Relay "Environment"

    中继“环境”将中继运行所需的配置、缓存存储和网络处理捆绑在一起。

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

    Answer: 因为只实例化一个新的 Relay.Environment() 比试图确保你已经清理了全局单例 Relay.Store 上的所有内容要干净得多。

    编辑:回应您的评论;

    Relay 目前提供了对何时重新获取数据的非常粗粒度的控制:primeCache 默认使用内存中的数据来完成查询,而 forceFetch 绕过缓存并从服务器完全重新获取数据。同样,在实践中,这对于我们的大多数用例都非常有效。


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

    关于缓存驱逐,重要的是要了解 Relay 与许多典型的缓存根本不同。典型的缓存存储独立的键/值对,而 Relay 缓存互连对象的图。我们在 Thinking in GraphQL 中广泛介绍了这一点的影响。在实践中,这意味着缓存驱逐的简单方法(例如 TTL 或 LRU)可能会产生不直观的后果。例如,产品通常关心查询,而缓存存储规范化的记录。如果甚至从缓存中逐出一条记录,它可能会导致整个查询有效地“丢失”并需要重新获取。此外,应用程序的离散部分的数据依赖关系可能会重叠,因此它们在数据的允许陈旧性方面存在分歧。

    【讨论】:

    • 虽然我认为这可能适用于只有一个查询的特定实例,但如果我只想重置缓存的一部分,只是 query { activeVideos { ... } } 的结果,而不是每个询问? (我也对如何将新环境引入系统感到困惑,但我认为这超出了这个问题的范围,因为我正在使用 foundfound-relay。)
    • 感谢您添加的详细信息。这就说得通了。现在我只需要弄清楚如何使用found 来做到这一点。
    • 如何将此解决方案与 found 集成的非常明显的答案是将 found 的路由器组件包装在另一个组件中,该组件在需要时传递一个新的解析器。仍在学习用 React 思考......
    • HoC 很棒
    猜你喜欢
    • 2016-05-13
    • 2016-12-05
    • 2018-12-05
    • 2020-09-25
    • 2016-05-30
    • 1970-01-01
    • 2018-04-08
    • 2020-05-09
    • 2021-01-03
    相关资源
    最近更新 更多