Как отключить кеш в apollo-link или apollo-client?
Я использую apollo-client, apollo-link и реагировать-apollo, я хочу полностью отключить кэш, но не знаю, как это сделать.
Я читаю источник apollo-cache-inmemory
, оно имеет config
аргумент в его конструкторе, но я не могу построить пустышку storeFactory
чтобы это работало.
4 ответа
Вы можете установить defaultOptions
вашему клиенту вот так:
const defaultOptions = {
watchQuery: {
fetchPolicy: 'network-only',
errorPolicy: 'ignore',
},
query: {
fetchPolicy: 'network-only',
errorPolicy: 'all',
},
}
const client = new ApolloClient({
link: concat(authMiddleware, httpLink),
cache: new InMemoryCache(),
defaultOptions: defaultOptions,
});
fetchPolicy
как network-only
избегает использования кеша.
Собственно, настройка fetchPolicy
в network-only
"по-прежнему сохраняет ответ в кэш для последующего использования, минуя чтение и форсируя сетевой запрос".
Если вы действительно хотите отключить кеш, читать и писать, используйте no-cache
,
Посмотрите официальные документы: https://www.apollographql.com/docs/react/advanced/caching.html
Я бы всегда предлагал не отключать встроенную функцию кеширования из клиента apollo. Вместо этого вы всегда можете установитьfetchPolicy: 'network-only'
по индивидуальным запросам. Что-то вроде этого
<Query
query={GET_DOG_PHOTO}
variables={{ breed }}
fetchPolicy='network-only'
>
{({ loading, error, data, refetch, networkStatus }) => {
...
}}
</Query>
При получении данных с помощью этого запроса он всегда будет выполнять сетевой запрос, а не сначала читать из кеша.
Хотя в ответе Ирвина Чана удалось отключить поведение кэширования Apollo, в ходе профилирования я обнаружил, что на самом деле он не отключает его полностью; «за кулисами» он по-прежнему добавляет контент в кеш, просто кеш не используется.
В моем случае это была проблема, поскольку само по себе поведение кэширования оказывало заметное влияние на производительность моего приложения. (~ 1 с накладных расходов на обработку в течение периода интенсивной загрузки данных ~ 20 с, т. е. ~ 5% потраченного процессорного времени)
Чтобы это исправить, я создал пустую альтернативу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; }
}
И я подключил его к клиенту 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",
},
},
});
Кажется, пока что он работает хорошо (избегая потери производительности), но я обновлю этот ответ, если с ним что-то не так и его нужно настроить.
(Примечание. Структура кеша apollo-client со временем изменилась. Мой ответ выше показывает только рабочую структуру на момент@apollo/client
версия3.7.15
. Проверьте историю ответов, если вам нужна структура для более старых версий:3.5.0-beta.4
.)