如何在apollo-link或apollo-client中禁用缓存?

Jac*_*Lee 33 react-apollo

我正在使用apollo-client,apollo-linkreact-apollo,我想完全禁用缓存,但不知道该怎么做.

我读了apollo-cache-inmemory它的源代码,它config的构造函数中有一个参数,但是我无法构建一个虚拟函数storeFactory来使它工作.

Irv*_*han 42

你可以defaultOptions像这样设置你的客户:

const defaultOptions = {
      watchQuery: {
        fetchPolicy: 'no-cache',
        errorPolicy: 'ignore',
      },
      query: {
        fetchPolicy: 'no-cache',
        errorPolicy: 'all',
      },
    }

const client = new ApolloClient({
    link: concat(authMiddleware, httpLink),
    cache: new InMemoryCache(),
    defaultOptions: defaultOptions,

});
Run Code Online (Sandbox Code Playgroud)

fetchPolicynetwork-only避免使用缓存.

  • 它不使用缓存,但是apollo仍在缓存所有数据...... (2认同)
  • 我认为在几乎所有用例中,最好仅在某些查询上禁用缓存。@Anuj 下面的答案可能是更好的解决方案。 (2认同)
  • 不知道为什么这被标记为正确答案,因为它不起作用。DefaultOptions 在 Apollo 中已经很长时间不起作用了,并且仍然没有修复。 (2认同)
  • 效果很好。谢谢 (2认同)

小智 36

实际上,设置fetchPolicynetwork-only "仍然保存对缓存的响应以供以后使用,绕过读取并强制网络请求".

如果你真的要禁用缓存,读取写入,使用no-cache.

看看官方文档:https://www.apollographql.com/docs/react/advanced/caching.html#ignore

  • 它说找不到页面。 (17认同)
  • apollo 客户端在缓存中保存响应多长时间? (2认同)

Anu*_*nuj 9

I would always suggest not to disable inbuild caching feature from apollo client. Instead you can always set fetchPolicy: 'network-only' for an individual queries. Something like this

<Query
    query={GET_DOG_PHOTO}
    variables={{ breed }}
    fetchPolicy='network-only'
>
 {({ loading, error, data, refetch, networkStatus }) => {
   ...
 }}
</Query>
Run Code Online (Sandbox Code Playgroud)

While fetching data with this Query, it would always do a network request instead of reading from cache first.

  • 能否知道为什么不建议禁用Apollo客户端的缓存? (6认同)
  • 我在一些边缘情况下使用“fetchPolicy:'仅限网络'”的解决方案仍在缓存中存储数据,并且在并发情况下不显示最新数据,这不是用户想要的。这取决于具体情况,但如果您想始终显示服务器的最新状态,我个人的建议是“无缓存”。它可以根据个人请求或整个客户进行设置。 (3认同)

Ven*_*ryx 6

虽然Irvin Chan 的答案确实设法禁用了 Apollo 的缓存行为,但我通过分析发现它实际上并没有完全禁用它;在幕后,它仍在向缓存添加内容,只是缓存没有被使用。

这对我来说是一个问题,因为缓存行为本身对我的应用程序造成了明显的性能影响。(约 1 秒的处理开销,在约 20 秒的繁重数据加载期间,即浪费了约 5% 的 CPU 时间)

为了解决这个问题,我创建了这个空的替代方案InMemoryCache

import {ApolloCache, NormalizedCacheObject} from "web-vcore/nm/@apollo/client.js";

const emptyCacheObj = {};
export class VoidCache extends ApolloCache<NormalizedCacheObject> {
    read(options) { return null; }
    write(options) { return undefined; }
    diff(options) { return {}; }
    watch(watch) { return ()=>{}; }
    async reset() {} // eslint-disable-line
    evict(options) { return false; }
    restore(data) { return this; }
    extract(optimistic) { return emptyCacheObj; }
    removeOptimistic(id) {}
    batch(options) { return undefined as any; }
    performTransaction(update, optimisticId) {}
    recordOptimisticTransaction(transaction, optimisticId) {}
    transformDocument(document) { return document; }
    transformForLink(document) { return document; }
    identify(object) { return undefined; }
    gc() { return [] as string[]; }
    modify(options) { return false; }
    readQuery(options, optimistic?) { return null; }
    readFragment(options, optimistic?) { return null; }
    writeQuery(opts) { return undefined; }
    writeFragment(opts) { return undefined; }
    updateQuery(options, update) { return null; }
    updateFragment(options, update) { return null; }
}
Run Code Online (Sandbox Code Playgroud)

我将它连接到 Apollo 客户端,如下所示:

apolloClient = new ApolloClient({
    // replace InMemoryCache with VoidCache, because even a "not used" InMemoryCache can have noticeable overhead
    cache: new VoidCache(),
    // these config-changes might not be necessary, but I've kept them anyway
    defaultOptions: {
        watchQuery: {
            fetchPolicy: "no-cache",
            errorPolicy: "ignore",
        },
        query: {
            fetchPolicy: "no-cache",
            errorPolicy: "all",
        },
    },
});
Run Code Online (Sandbox Code Playgroud)

到目前为止,它似乎运行良好(避免了性能损失),但如果有问题并且需要调整,我会更新这个答案。

(注意:apollo-client 的缓存结构随着时间的推移而发生了变化。我上面的答案仅显示了版本 的工作结构@apollo/client3.7.15如果您需要旧版本的结构,请检查答案历史记录:3.5.0-beta.4。)