【问题标题】:Graphql - Apollo Client/ React - Cache - fetchMore doesn't update the data state of the queryGraphql - Apollo Client/ React - Cache - fetchMore 不更新查询的数据状态
【发布时间】:2022-08-17 10:18:13
【问题描述】:

我尝试在使用 apollo 客户端的反应应用程序中实现缓存分页。

我的查询有 filter 参数,它应该是在缓存对象中创建新键的唯一参数。

由于某种原因,当 fetchMore 发生指定过滤器时,新数据不会导致组件中的重新渲染。

我在合并函数中记录了现有参数和传入参数,似乎对于每个具有过滤器的 fetchMore,新数据确实到达了。所以,我不明白为什么组件没有重新渲染。

让事情变得更糟:在有或没有过滤器的情况下多次调用 fetchMore 发送 http 请求并将传入数据与现有数据合并。我希望不会发生这种情况,因为客户端应该看到它在缓存中已经有一个带有该键参数的查询的键。

以下是查询:

query Shells($first: Int = 5, $offset: Int = 0, $filter: ShellFilter) {
  shells(
    orderBy: [STATUS_ASC, EXECUTION_FROM_DESC]
    first: $first
    offset: $offset
    filter: $filter
  ) {
    nodes {
      ...ShellData
    }
    totalCount
  }
}

apolloClient 配置是这样的:

const client = new ApolloClient({
  cache: new InMemoryCache({
    typePolicies: {
      Query: {
        fields: {
          shells: {
            keyArgs: [\'filter\'],
            merge: (existing, incoming) => {
              console.log(\'existing:\', existing, \'incoming:\', incoming);
              return mergeObjectsAndNestedArrays<ShellsConnection>(
                existing,
                incoming,
                \'nodes\',
              );
            },
          },
        },
      },
    },
  })

以及显示它的组件:

const ControlCenter = () => {
  const { showModal } = useModalContext();
  const [page, setPage] = useState(1);
  const { data, loading, fetchMore } = useShellsQuery();
  const [query, setQuery] = useURLQuery();

  const onCounterpartiesChange = async (counterparties) => {
    await fetchMore({
      variables: {
        filter: { shellCounterParties: { some: { orgId: { in: \'20584\' } } } },
      },
    });
    setQuery({ counterparties });
  };

  const shells = data?.shells?.nodes;

  console.log(\'hello from shells:\', shells);

这些是日志:

  • 更新 useEffect 中的状态。然后它将触发渲染。
  • 似乎是一个补丁。 fetchMore 没有过滤器 arg,重新渲染了没有 useEffect 的组件。
  • 以防万一,您是否确保mergeObjectsAndNestedArrays 返回数据的确切形状?另外,最好使用apollo devtools 检查 apollo 缓存数据

标签: reactjs caching graphql apollo-client


【解决方案1】:

我认为问题在于您在代码中使用keyArgs: ['filter'] 定义了typePolicies

请查看官方文档:

https://www.apollographql.com/docs/react/caching/cache-configuration/#customizing-cache-ids

You can customize how the InMemoryCache generates cache IDs for individual types in your schema

This is helpful especially if a type uses a field (or fields!) besides id or _id as its unique identifier.

基于此,您已将 filter 定义为唯一标识符,即使这是用于过滤目的的变量。它不是一个场地自定义缓存但是一个变量。

Note that these keyFields strings always refer to the actual field names as defined in your schema, meaning the ID computation is not sensitive to field aliases.

我的建议首先是修改您设置的配置,看看是否有帮助?

【讨论】:

    猜你喜欢
    • 2017-12-02
    • 2020-03-27
    • 2022-07-21
    • 2018-02-10
    • 2017-07-21
    • 2021-02-18
    • 2018-07-07
    • 2018-11-06
    • 2017-12-20
    相关资源
    最近更新 更多