【问题标题】:Apollo 3 pagination with Field PoliciesApollo 3 分页与现场策略
【发布时间】:2020-10-25 18:29:01
【问题描述】:

谁能提供一个使用 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;

【问题讨论】:

    标签: reactjs pagination react-apollo apollo-client


    【解决方案1】:

    彻底移除 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 ex。输入 keyArg: offsetLimitPagination(["filters"]) 并使用过滤器 arg 查询您的用户。缓存会单独存储。

    更多信息official release

    【讨论】:

    • 它对我不起作用。你能帮助我吗? codesandbox.io/s/nostalgic-glitter-y7350?file=/src/index.js
    • @DarynK。它确实有效。 typePolicies 是 InMemoryCache 实例的选项。使用索引来迭代反应组件也是反模式。 codesandbox.io/s/stoic-haze-ispw2
    • 这么多令人困惑的元素。一,我的后端采用变量“skip”而不是偏移量。有没有办法将其配置为使用跳过?另外,我正在实现无限滚动。如果没有 fetchmore,我们如何抓取下一个日志?
    【解决方案2】:

    供未来的用户使用。在 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 可以是除 limitoffset 之外的其他参数。

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

    【讨论】:

    • ,查询新数据时,自定义合并功能不重新渲染UI。如何自动重新渲染 UI。除了我调用 useQuery 钩子来重新渲染 ui 之外,我还需要调用一些方法吗?
    • 不确定您是如何设置查询的,但是,我认为值得一提的是,如果您还在查询中传递变量,则需要像我在上面所做的那样在 keyArgs 中传递它们(keyArgs: ["searchString", "type"]).
    猜你喜欢
    • 2021-02-01
    • 2021-02-16
    • 1970-01-01
    • 2018-07-18
    • 2014-11-01
    • 1970-01-01
    • 2021-09-01
    • 2023-01-08
    • 2019-09-20
    相关资源
    最近更新 更多