带有字段策略的 Apollo 3 分页

IT技术 reactjs pagination react-apollo apollo-client
2021-05-09 10:08:28

有人可以提供一个使用 Apollo Client 3.0 字段策略实现的分页示例。我一直在按照文档中的示例来实现无限滚动,但在我的控制台中,我收到以下警告:

The updateQuery callback for fetchMore is deprecated, and will be removed
in the next major version of Apollo Client.

Please convert updateQuery functions to field policies with appropriate
read and merge functions, or use/adapt a helper function (such as
concatPagination, offsetLimitPagination, or relayStylePagination) from
@apollo/client/utilities.

The field policy system handles pagination more effectively than a
hand-written updateQuery function, and you only need to define the policy
once, rather than every time you call fetchMore.

我对 Apollo 相当陌生,我真的不知道如何以 3.0 的方式做到这一点。我会很感激一些例子来更好地理解。

这是我当前的代码:

import React from "react";
import { useGetUsersQuery } from "./generated/graphql";
import { Waypoint } from "react-waypoint";

const App = () => {
  const { data, loading, error, fetchMore } = useGetUsersQuery({
    variables: { limit: 20, offset: 0 },
  });

  if (loading) return <div>Loading...</div>;
  if (error) return <div>Error</div>;

  return (
    <div className="App">
      {data && data.users && (
        <div>
          {data.users.map((user, i) => {
            return (
              <div key={i} style={{ margin: "20px 0" }}>
                <div>{user.id}</div>
                <div>{user.name}</div>
              </div>
            );
          })}
          <Waypoint
            onEnter={() => {
              fetchMore({
                variables: { offset: data.users.length },
                updateQuery: (prev, { fetchMoreResult }) => {
                  console.log("called");
                  if (!fetchMoreResult) return prev;
                  return Object.assign({}, prev, {
                    users: [...prev.users, fetchMoreResult.users],
                  });
                },
              });
            }}
          />
        </div>
      )}
    </div>
  );
};

export default App;
2个回答

完全移除 updateQuery 回调函数:

fetchMore({ variables: { offset: data.users.length } });

并将您的缓存更改为:

import { offsetLimitPagination } from "@apollo/client/utilities";

const cache = new InMemoryCache({
  typePolicies: {
    Query: {
      fields: {
        users: offsetLimitPagination(),
      },
    },
  },
});

所以你在 qraphql 中的查询必须有 offset 和 limit 参数。

其他选项是:concatPaginationrelayStylePagination

如果您需要区分对同一字段的不同请求,users例如。放入 keyArg:offsetLimitPagination(["filters"])并使用过滤器 arg 查询您的用户。缓存将其单独存储。

官方发布的更多信息

对于未来的用户。您可以通过以下方式在 Aplo > 3.0.0 中实现缓存更新。

const cache = new InMemoryCache({
  typePolicies: {
    Query: {
      fields: {
        users: {
          keyArgs: ["searchString", "type"],
          // Concatenate the incoming list items with
          // the existing list items.
          merge(existing = [], incoming) {
            return [...existing, ...incoming];
          },
        }
      }
    }
  }
})

searchStringtype可能是除了limit & offset之外的其他参数

这样你就不需要在updateQuery回调中做任何更新逻辑