【问题标题】:Apollo GraphQL updateQuery to typePolicyApollo GraphQL updateQuery 到 typePolicy
【发布时间】:2020-12-20 16:40:39
【问题描述】:

我正在用头撞墙。我已更新到 Apollo 3,但无法弄清楚如何将 updateQuery 迁移到 typePolicy。我正在做基本的基于延续的分页,这就是我用来合并fetchMore的结果的方式:

await fetchMore({
  query: MessagesByThreadIDQuery,
  variables: {
    threadId: threadId,
    limit: Configuration.MessagePageSize,
    continuation: token
  },
  updateQuery: (prev, curr) => {
    // Extract our updated message page.
    const last = prev.messagesByThreadId.messages ?? []
    const next = curr.fetchMoreResult?.messagesByThreadId.messages ?? []

    return {
      messagesByThreadId: {
        __typename: 'MessagesContinuation',
        messages: [...last, ...next],
        continuation: curr.fetchMoreResult?.messagesByThreadId.continuation
      }
    }
  }

我曾尝试自己编写mergetypePolicy,但它只是不断加载并抛出有关 Apollo 缓存中重复标识符的错误。这是我的typePolicy 查询时的样子。

  typePolicies: {
    Query: {
      fields: {
        messagesByThreadId: {
          keyArgs: false,
          merge: (existing, incoming, args): IMessagesContinuation => {
            const typedExisting: IMessagesContinuation | undefined = existing
            const typedIncoming: IMessagesContinuation | undefined = incoming
            const existingMessages = (typedExisting?.messages ?? [])
            const incomingMessages = (typedIncoming?.messages ?? [])

            const result = existing ? {
              __typename: 'MessageContinuation',
              messages: [...existingMessages, ...incomingMessages],
              continuation: typedIncoming?.continuation
            } : incoming


            return result
          }
        }
      }
    }
  }

【问题讨论】:

    标签: javascript typescript graphql apollo typepolicies


    【解决方案1】:

    所以我能够解决我的用例。这似乎比它真正需要的要困难得多。我基本上必须尝试找到与传入匹配的现有项目并覆盖它们,以及添加缓存中尚不存在的任何新项目。

    如果提供了延续令牌,我还必须仅应用此逻辑,因为如果它为 null 或未定义,我应该只使用传入的值,因为这表明我们正在执行初始加载。

    我的文档是这样的:

    {
      "items": [{ id: string, ...others }],
      "continuation": "some_token_value"
    }
    

    我创建了一个通用类型策略,可以将其用于所有具有相似形状的文档。它允许我指定 items 属性的名称、我想要缓存的关键参数是什么以及 graphql 类型的名称。

    export function ContinuationPolicy(keyArgs: Array<string>, itemPropertyKey: string, typeName: string) {
      return {
        keyArgs,
        merge(existing: any, incoming: any, args: any) {
          if (!!existing && !!args.args?.continuation) {
            const existingItems = (existing ? existing[itemPropertyKey] : [])
            const incomingItems = (incoming ? incoming[itemPropertyKey] : [])
            let items: Array<any> = [...existingItems]
    
            for (let i = 0; i < incomingItems.length; i++) {
              const current = incomingItems[i] as any
              const found = items.findIndex(m => m.__ref === current.__ref)
    
              if (found > -1) {
                items[found] === current
              } else {
                items = [...items, current]
              }
            }
    
            // This new data is a continuation of the last data.
            return {
              __typename: typeName,
              [itemPropertyKey]: items,
              continuation: incoming.continuation
            }
          } else {
            // When we have no existing data in the cache, we'll just use the incoming data.
            return incoming
          }
        }
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2018-06-09
      • 1970-01-01
      • 2017-03-05
      • 2020-02-03
      • 2018-03-20
      • 2020-12-10
      • 2020-10-05
      • 2020-12-14
      • 2019-07-23
      相关资源
      最近更新 更多