使用 cache.modify 更新字段后未调用自定义合并函数

Custom merge function is not being called after updating field with cache.modify

我已经为类型 Session 上的字段 products 编写了自定义合并函数。合并函数似乎只在我用它的 products 初始化对象 Session:1 时被调用,而不是当我稍后使用 cache.modify.

更新 products 时被调用

我的合并函数:

const client = new ApolloClient({
  uri: 'http://localhost:8081/graphql',
  cache: new InMemoryCache({
    typePolicies: {
      Session: {
        fields: {
          products: {
            merge (existing, incoming) {
              // this is only being called on useQuery(HydrateSession), not useMutation(UpsertProduct)
              console.log('existing', JSON.stringify(existing, null, 2))
              console.log('incoming', JSON.stringify(incoming, null, 2))
              // remove duplicates when latestProduct has the same id as an existing product — [..., latestProduct]
              if (incoming.filter(p => p.id === incoming[incoming.length - 1].id).length > 1) return existing
              return incoming
            }
          }
        }
      }
    }
  })
})

Session的初始化:

const HydrateSession = gql`
  query {
    session {
      id
      products {
        id
      }
    }
  }
`

...

useQuery(HydrateSession)

稍后使用 cache.modify 更新 products:

const UpsertProduct = gql`
  mutation UpsertProduct($product: ProductInput!) {
    upsertProduct(product: $product) {
      id
    }
  }
`

...

const [upsertProductMutation] = useMutation(UpsertProduct)

const onClick = async () => {
  await upsertProductMutation({
    variables: {
      product: {
        id: 2
      }
    },
    update: (cache, mutationResult) => {
      cache.modify({
        id: 'Session:1',
        fields: {
          products: previous => [...previous, mutationResult.data.upsertProduct]
        }
      })
    }
  })
}

我这里有一个完整的工作示例 https://github.com/jsindos/apollo-play、运行 npm i,然后使用 npm startnpm serve 启动两个单独的进程。单击触发突变的按钮后,合并功能不是 运行(从控制台中没有 console.log 语句可以看出)。

modify circumvents any merge functions you've defined, which means that fields are always overwritten with exactly the values you specify.

阅读文档是一件好事。