0Pricing
React Academy · Урок

Кэш Apollo: нормализация и обновления

Разберитесь в нормализованном InMemoryCache Apollo и обновляйте кэшированные данные после мутаций без повторной загрузки

«Кэш Apollo: нормализация и обновления» — бесплатный урок React Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения React Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс React Academy содержит 4 уроков всего.

Как InMemoryCache нормализует данные

InMemoryCache сохраняет каждый объект по ключу кэша, составленному из __typename и id: User:1, Post:42. Когда запрос возвращает User с id "1", объект сохраняется один раз по этому ключу независимо от того, сколько разных запросов его содержит.

Каждый последующий запрос, получающий тот же User:1, читает данные из единственной записи кэша, поэтому все компоненты видят одинаковые данные.

Автоматическое обновление между запросами

Когда мутация возвращает обновлённый объект User:1, Apollo записывает его в запись кэша User:1. Каждый активный запрос, содержавший User:1, автоматически отражает обновлённые поля в интерфейсе без дополнительного кода.

Такое автоматическое распространение изменений — главное преимущество нормализованного кэша перед кэшем документов, организованным по ключам запросов.

cache.readQuery

Прочитайте текущий результат запроса из кэша: cache.readQuery({ query: GET_USERS }) возвращает объект данных так, как если бы его вернул useQuery. Возвращается null, если запроса нет в кэше.

Используйте readQuery внутри функций обновления мутации, чтобы прочитать текущий список перед его изменением.

cache.writeQuery

cache.writeQuery({ query: GET_USERS, data: { users: updatedUsers } }) напрямую записывает данные в кэш, вызывая повторный рендеринг всех компонентов, которые читают GET_USERS. Сетевой запрос не выполняется.

Объединяйте readQuery и writeQuery для реализации неизменяемых обновлений кэша: прочитайте данные, создайте новый массив и запишите его обратно.

cache.modify для прямого обновления сущностей

cache.modify({ id: cache.identify(user), fields: { name: () => 'New Name' } }) напрямую изменяет поля конкретной сущности в кэше. Сначала читать запрос не нужно, если вы знаете идентификатор сущности в кэше.

Объект полей сопоставляет имена полей с функциями-модификаторами, которые получают текущее значение и возвращают новое.

Обновление кэша после мутации

Передайте функции обновления в useMutation: useMutation(ADD_POST, { update(cache, { data: { addPost } }) { cache.modify({ id: cache.identify(user), fields: { posts: existingPosts => [...existingPosts, addPost] } }); } }).

Это добавляет новую публикацию в массив публикаций пользователя в кэше и обновляет все компоненты, отображающие список публикаций пользователя.

cache.evict: удаление записей кэша

cache.evict({ id: 'User:1' }) удаляет запись User:1 из кэша. Любой активный запрос, содержавший User:1, повторно отрендерится без этой сущности в результате.

После удаления записей вызовите cache.gc(), чтобы удалить объекты, которые теперь недостижимы из корневых запросов. Это предотвращает утечки памяти в приложениях, работающих длительное время.

Сборка мусора

cache.gc() обходит граф кэша, начиная со всех активных запросов, и удаляет сущности, которые больше недостижимы. Этот метод безопасно вызывать периодически или после пакетных мутаций, удаляющих множество сущностей.

Сущности, на которые ссылаются активные хуки useQuery, никогда не удаляются сборщиком мусора; удаляются только осиротевшие сущности, больше не входящие ни в один результат запроса.

Перенаправление кэша с помощью политик полей

Если вы запрашиваете отдельную сущность (GET_USER по идентификатору), которая уже сохранена в кэше как часть запроса списка, Apollo может прочитать её из кэша без дополнительного сетевого обращения с помощью политик полей: keyArgs и функций чтения в политике типа.

Функция чтения возвращает ссылку на кэш: return toReference({ __typename: 'User', id: args.id }), указывая Apollo прочитать данные из существующей записи кэша User:id.

Пользовательские keyFields для нестандартных идентификаторов

Если ваши сущности используют в качестве уникального ключа поле, отличное от id (например, slug или uuid), настройте его в политике типа: new InMemoryCache({ typePolicies: { Post: { keyFields: ['slug'] } } }).

После этого Apollo использует Post:my-post-slug как ключ кэша вместо обязательного поля id, сохраняя нормализацию для нестандартных схем.

refetchQueries и функция обновления

refetchQueries: [{ query: GET_USERS }] в параметрах useMutation запускает повторный сетевой запрос после завершения мутации. Это проще, но всегда приводит к сетевому запросу.

Функция обновления изменяет кэш локально и избегает дополнительного сетевого обращения. Используйте refetchQueries, когда логику обновления кэша слишком сложно написать или когда вычисляемые сервером поля делают локальные обновления кэша ненадёжными.

Ключ нормализации InMemoryCache

Какой формат ключа кэша по умолчанию использует InMemoryCache для хранения сущностей?

Итоги урока

InMemoryCache нормализует сущности по __typename+id, обеспечивая автоматические обновления между запросами. Читайте и записывайте данные кэша с помощью cache.readQuery, cache.writeQuery и cache.modify. Удаляйте сущности с помощью cache.evict, а затем cache.gc. Настраивайте пользовательские поля ключа через typePolicies для первичных ключей, отличных от id.

Используйте функции обновления мутаций для эффективной работы с локальным кэшем; применяйте refetchQueries, когда вычисляемые сервером поля делают локальные обновления ненадёжными.

Часто задаваемые вопросы

Урок «Кэш Apollo: нормализация и обновления» бесплатный?

Да — полный текст урока «Кэш Apollo: нормализация и обновления» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс React Academy, подпишись на CoddyKit PRO. Курс React Academy содержит 4 уроков всего.

Чему я научусь в уроке «Кэш Apollo: нормализация и обновления»?

Разберитесь в нормализованном InMemoryCache Apollo и обновляйте кэшированные данные после мутаций без повторной загрузки Ты практикуешь React Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать React Academy?

Предыдущий опыт не требуется. React Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.

Сколько времени занимает урок «Кэш Apollo: нормализация и обновления»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке React Academy?

Да. Каждый урок React Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Основы GraphQL для разработчиков React
  2. Настройка Apollo Client в React
  3. Хуки useQuery и useMutation
  4. Кэш Apollo: нормализация и обновления
← Назад к React Academy