【问题标题】:Apollo Client refetch() is not updating cache when the response from server is empty list当来自服务器的响应为空列表时,Apollo Client refetch() 不会更新缓存
【发布时间】:2023-04-06 05:08:01
【问题描述】:

每当 useQuery 的变量发生变化时,我都会使用refetch() 来过滤列表。每次更改变量 prop 时,它都会根据过滤器获取结果,当服务器的结果为空列表 [] 时,refetch() 方法返回缓存的结果而不是空列表 []。

const { loading, error, data, fetchMore, refetch } = useQuery(Users, {
    variables: {
      userNumber: userNum,
    },
  });

useEffect(() => {
    if (userNum){
      refetch();
    } 
    }, [userNum]);

因此,每次 userNum 属性随具有此 userNum 的用户列表更改时,它都会获取更新的结果,但是,如果从服务器返回的用户列表为空(因为没有用户拥有此编号),我可以看到上一个缓存结果而不是空列表。

我试过了

fetchPolicy: 'cache-and-network', 
nextFetchPolicy: 'cache-first', 

并且仍然得到缓存的结果而不是空列表。

我也尝试过 typePolicies 中的 merge() 并且它有效!但是,当我应用 relayStylePagination 时,它会再次获取缓存的结果,而不是空列表。

uri: 'http://localhost:5000/graphql',
cache: new InMemoryCache({
  typePolicies: {
    Query: {
      fields: {
        devices: relayStylePagination(),
        merge(existing = {}, incoming) {
          return { ...existing, ...incoming };
        },
      },
    },
  },
}),
});

我也尝试过使用 keyfields,并且当服务器返回空列表时缓存会更新,但是中继分页不起作用。让中继分页工作的唯一方法是像这样放置它:

fields: {
          devices: relayStylePagination(),
        },

` 我的查询是这样的:

 $after: ID
 $userNum: Int
 $dpiGt: String
 $dpiLt: String
) {
 users(
   after: $after
   userNumber: $userNum
   first: 30
   filter: { dpiGt: $dpiGt, dpiLt: $dpiLt }
 ) {
   edges {
     cursor
     node {
       id
       name
       userNumber
     }
   }
   pageInfo {
     endCursor
     hasNextPage
   }
 }
}

系统详情:

OS: macOS 10.15.4
Binaries:
Node: 12.16.1 - ~/n/bin/node
Yarn: 1.21.1 - /usr/local/bin/yarn
npm: 6.13.4 - ~/n/bin/npm
Browsers:
Chrome: 86.0.4240.80
Firefox: 81.0.1
Safari: 13.1
npmPackages:
@apollo/client: ^3.2.3 => 3.2.5

【问题讨论】:

  • 你解决了吗?

标签: caching react-apollo apollo-client apollo-cache-inmemory


【解决方案1】:

不确定这是否能解决您的问题,但值得一试。

在调查并阅读了 refetch section 下的 Apollo 文档后,我发现此描述可能对您的用例有用。

幸运的是,useQuery 钩子的结果对象通过 networkStatus 属性提供了有关查询状态的细粒度信息。为了利用这些信息,我们需要将 notifyOnNetworkStatusChange 选项设置为 true,以便我们的查询组件在重新获取过程中重新呈现:

import { useQuery, NetworkStatus } from '@apollo/client';

...

const { loading, error, data, fetchMore, refetch, networkStatus } = useQuery(Users, { 
    variables: {
      userNumber: userNum,
    },
     notifyOnNetworkStatusChange: true, 
  });
  

 if (networkStatus === NetworkStatus.refetch) return <div>Refetching!</div>; 
 
 ...

【讨论】:

    猜你喜欢
    • 2021-05-09
    • 1970-01-01
    • 2013-04-09
    • 2022-07-13
    • 2018-09-02
    • 2020-10-14
    • 2021-04-18
    • 2014-11-09
    • 2020-09-14
    相关资源
    最近更新 更多