首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用缓存但仍从服务器获取的阿波罗分页查询(即使存在查询变量的缓存)

使用缓存但仍从服务器获取的阿波罗分页查询(即使存在查询变量的缓存)
EN

Stack Overflow用户
提问于 2022-11-14 07:45:08
回答 1查看 56关注 0票数 0

我已经在我的服务器上实现了一个限制偏移量分页查询,我是从前端查询的。分页看起来很好,但是缓存并没有像我所期望的那样工作。

我对预期行为的假设是,当我请求下一页时,下一页的数据值将从服务器中获取,但当我单击back按钮时,查询应该只从缓存中提取,因为该数据以前已经从服务器中提取(当该页面先前被请求时),因此不需要对服务器进行查询。

这在我的应用程序中有些类似的情况,但并不完全是这样。当我向前进一个页面时,我可以看到页面填充需要时间,这意味着服务器正在被查询,因此也就是加载时间。当我返回一个页面时,它会立即被填充,这意味着页面数据是按照预期从缓存中获取的,然而,当我在该查询中从服务器控制台日志并在chrome中查看网络时,我可以看到客户机实际上是在查询服务器,尽管它也从缓存中读取数据。

如果以前使用相同的偏移量和限制变量查询数据,我不希望客户机从服务器获取数据,而只是从缓存中获取数据。

这是我的缓存:

代码语言:javascript
复制
  const cache = new InMemoryCache({
    typePolicies: {
      Query: {
        fields: {
          privateCloudProjectsPaginated: offsetLimitPagination(),
        },
      },
    },
  });

这是客户端组件:

代码语言:javascript
复制
export default function Projects() {
  const { debouncedSearch } = useContext(SearchContext);
  const { filter } = useContext(FilterContext);

  const { loading, data, fetchMor, error } = useQuery(ALL_PROJECTS, {
    nextFetchPolicy: "cache-first",
    variables: {
      offset: 0,
      limit: 10,
    },
  });

  const getNextPage = useCallback(
    (page, pageSize) => {
      fetchMore({
        variables: {
          offset: page * pageSize,
          limit: pageSize,
        },
      });
    },
    [filter, debouncedSearch, fetchMore]
  );

  if (error) {
    return <Alert error={error} />;
  }

  return (
    <StickyTable
      onClickPath={"/private-cloud/admin/project/"}
      onNextPage={getNextPage}
      columns={columns}
      rows={
        loading ? [] : data.privateCloudProjectsPaginated.map(projectsToRows)
      }
      count={loading ? 0 : data.privateCloudProjectsCount}
      title="Projects"
      loading={loading}
    />
  );
}

我已经尝试过许多fetchPolicynextFetchPolicy,但是没有任何效果。此外,我的表组件处理项目数据的切片,因此缓存只返回所有现有数据。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-11-18 18:56:39

在这种情况下,要将每个查询的结果限制为您请求的项,可以在您的字段策略中包含一个分页的read函数。正如文档中所建议的那样,由于offsetLimitPagination助手当前正在定义字段策略,所以可以将读取函数与助手的结果组合起来,如下所示:

代码语言:javascript
复制
const cache = new InMemoryCache({
  typePolicies: {
    Query: {
      fields: {
         privateCloudProjectsPaginated: {
              ...offsetLimitPagination(),
              read(existing, { args }) {
                // Implement here
              }
        },
      },
    },
  },
});

这应该允许客户端重新分页列表。引用文档中关于read函数的更多的read可能是什么样子可能是有帮助的。从这些例子中可以看出一个重要的注释:

如果现有函数未定义,则读取函数应始终返回未定义的。返回未定义的信号,说明缓存中缺少该字段,这指示阿波罗客户端从您的GraphQL服务器获取其值。

在所有情况下,如果使用分页读取函数,那么根据用例的要求正确更新偏移量和限制变量是非常重要的,以防止重复的页面呈现。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74428361

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档