Apollo 客户端缓存无法正常工作 [英] Apollo client cache doesn't work as I excpected

查看:46
本文介绍了Apollo 客户端缓存无法正常工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题:

我对 GraphQL 非常陌生,我正在使用 Apollo 服务器和客户端开发我的第一个全栈应用程序,这是一个简单的博客.

I am pretty new to GraphQL and I am developing my first full stack app using Apollo server and client, which is a simple blog.

在客户端,我在两个不同的页面中使用相同的查询,但具有不同的变量.查询是通过 ID 或 slug 查询博客文章,具体取决于我使用的页面.所以结果是一样的,只是查询变量发生了变化.

On client side, I am using the same query in two different pages, but with different variables. Queries are querying a blog article by ID or slug, depending on the page I am using it. So the result is the same, there is just the queries variables that changes.

当我在一页中使用查询时,我认为查询不会因为 Apollo 缓存而在第二页上运行.但这不是正在发生的事情.查询在第二个页面再次运行,当然返回与其他页面相同的结果.

When I use a query in one page, I thought query wouldn't run on the second page because of Apollo cache. But it is not what is happening. The query runs again in the second, and of course returns me the same result that in the other page.

为什么 Apollo 在这种情况下不使用缓存?

Why does Apollo doesn't use the cache in this case?

这是我使用的代码:

在服务器端,我有一个非常基本的查询来从博客中获取一篇文章,可以通过 ID 或 Slug 获取:

On server side, I have a pretty basic query to fetch an article from a blog, which can be fetched by ID or Slug:

type Query {
  ...
  article(id: ID, slug: String): Article
  ...
}

在客户端,如果文章已发布,我会通过 slug 查询文章,或者当它仍然是草稿时通过 ID 查询.

On client side, I query an article by slug if the article is published, or by ID when it is still a draft.

slug 查询:

<Query
  query={article}
  variables={{ slug }}
  fetchPolicy="cache-and-network"
>
  {({ loading, error, data }) => {
    return (
      <Article
        loading={loading}
        article={data && data.article}
      />
    );
  }}
</Query>

通过ID查询是一样的,除了使用ID的变量param:

The query by ID is the same, except the variables param which uses ID:

<Query
  query={article}
  variables={{ id }}
>
  {({ loading, error, data }) => {
    return (
      <EditArticle loading={loading} article={data && data.article} />
    );
  }}
</Query>

如您所见,两者都使用相同的 GraphQL 端点,结果相同.但是没有使用缓存.

As you can see, both are using the same GraphQL endpoint, and the result is the same. But the cache is not used.

推荐答案

Apollo 假定您的解析器是纯解析器(它们没有副作用,并且在给定相同的输入/参数的情况下通常返回相同的结果).这已经是很多假设了.想象一个解析器返回一个随机数或新闻网站上的最新评论.给定相同的输入,两者并不总是返回相同的结果.另一方面,Apollo 不会——而且几乎不能——对解析器的实现做出假设.虽然在您的脑海中,文章解析器的实现是显而易见的(如果 id 存在,则返回具有该 id 的文章,如果 slug 存在,则返回带有该 slug 的文章)这是很多问题需要从计算机程序中进行猜测.

Apollo assumes that your resolvers are pure (they don't have side effects and formostly return the same result given the same input/arguments). This is already a lot to assume. Imagine a resolver that returns a random number or the newest comment on a news website. Both would not always return the same result given the same input. On the other hand Apollo does not make - and pretty much cannot make - assumptions about the implementation of your resolver. While in your head the implementation for your article resolver is obvious (if the id is present return article with that id, if slug is present return article with that slug) this is a lot to ask from a computer programm to guess.

我最近回答了一个类似的问题.为了防止第二个查询运行,你必须实现一个 缓存重定向.缺点是您必须使客户端上的缓存重定向和服务器上的解析器保持同步.

I have answered a similar question recently. To prevent the second query from running you have to implement a cache redirect. The downside is that you have to keep your cache redirects on the client and resolvers on the server in sync.

这篇关于Apollo 客户端缓存无法正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆