使用 Field Policies 的 Apollo 3 分页

Apollo 3 pagination with Field Policies

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

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;

完全删除 updateQuery 回调函数:

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

并将您的缓存更改为:

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

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

因此您在 qraphql 中的查询必须具有偏移量和限制参数。

其他选项有:concatPaginationrelayStylePagination

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

更多信息见official release

对于未来的用户。 Apllo > 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 & [=18 之外的其他参数=]偏移.

这样您就不需要在 updateQuery 回调中执行任何更新逻辑。