0

我有两个简单的查询:

query GerMenuA {
  menus {
    menuA {
      items {
        label
      }
    }
  }
}

query GerMenuB {
  menus {
    menuB {
      items {
        label
      }
    }
  }
}

但在控制台中我看到一个警告:

Cache data may be lost when replacing the menus field of a Query object.
existing: {"__typename":"Menu","menuA":[{...}]}
incoming: {"__typename":"Menu","menuB":[{...}]}

有没有办法不合并它们并删除警告?因为如果指定在typePolicies

Menu: { merge: true }
or
Menu: { merge: false }

这不是我想要的,因为这些是不同的数据,这两个队列不需要以任何方式合并。另外,我没有id字段并且keyFields不适用于这种情况,因为两个菜单的标签可能相同

4

1 回答 1

1

因此,如果没有您的架构类型定义,您的问题很难回答。但是让我们假设它是这样的:

type Query {
  menus: Menus
}
type Menus {
  menuA: Menu
  menuB: Menu
}

警告本质上是说没有任何keyArgsApollo Cache 就无法规范化menus查询。从他们的角度记住——你有一个单一的 menus 查询。(即GerMenuA并且GerMenuB是客户端查询而不是查询)。

(旁注 - 因为您没有id字段,请参阅禁用规范化。)

选项 1:分离您的查询

type Query {
  menuA: Menu
  menuB: Menu
}

Apollo 缓存现在将存储menuAmenuB作为单独的查询。如果你想安全,你可以设置你的类型策略:

const createCache = () => new InMemoryCache({
  typePolicies: {
    Menu: {
      keyFields: false
    },
    Query: {
      fields: {
        menuA: {
          keyArgs: false
        },
        menuB: {
          keyArgs: false
        }
      }
    }
  },
});

keyFields: false告诉 AC 存储Menu在它的父查询下。keyArgs: falsemenuAmenuB都是单例查询。缓存策略将默认为merge: false现有数据将被传入数据替换。

选项 2:定义查询参数

在此选项中,您name向查询添加参数menus

type Query {
  menus(name: String): Menu
}

默认情况下,缓存会为您在查询特定字段时提供的每个唯一参数值组合存储一个单独的值。

Apollo 缓存现在将存储menus:{name:menuA}menus:{name:menuB}作为单独的缓存对象。同样,如果你想安全,你可以设置你的类型策略:

const createCache = () => new InMemoryCache({
  typePolicies: {
    Menu: {
      keyFields: false
    }
  },
});

同样,缓存策略将默认为merge: false现有数据将被传入数据替换。

选项 3:定义合并策略

我们已经讨论了为什么现有模式对 Apollo Cache 感到困惑。但是如果你真的准备好了,剩下要做的就是定义一个合并策略:

const createCache = () => new InMemoryCache({
  typePolicies: {
    Menu: {
      keyFields: false
    },
    Menus: {
      keyFields: false,
      merge: true
    },
    Query: {
      fields: {
        menus: {
          keyArgs: false,
          merge: true
        }
      }
    }
  },
});

merge: true告诉 Apollo Cache 将 和 的结果合并GerMenuA到具有和属性GerMenuB的单个Menus缓存对象中。如果没有它,每次运行查询时都会破坏前一个查询的结果。menuAmenuB

于 2021-02-24T00:48:17.587 回答