1

每当 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
4

1 回答 1

0

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

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

幸运的是,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-06-02T12:23:42.420 回答