Інвалідація кешу
Що таке інвалідація кешу
Інвалідація (cache invalidation) - це процес примусового оновлення або видалення застарілих даних із кешу після того, як вихідні дані (на сервері або в БД) змінилися.
Тобто, якщо користувач або застосунок змінили дані, кеш повинен перестати вважати їх актуальними і запросити свіжі.
Чому це критично
1. Щоб користувач не бачив старі дані
Приклад:
await fetch('/api/user/1', { method: 'PATCH', body: { name: 'Alex' } });Ти змінив ім'я користувача на сервері. Якщо кеш (/api/user/1) не інвалідується, компонент продовжить показувати старе ім'я - React думатиме, що «все гаразд, дані вже є».
UI відстає від реальності. Користувач бачить стару інформацію, а API вже давно оновилося.
2. Щоб уникнути логічних помилок
Якщо інші частини застосунку використовують ці самі дані (наприклад, список користувачів і профіль), то за зміни одного з них увесь застосунок може розходитися в даних.
Список показує «Alex», а картка - «Alexander».
Причина - кеш не був інвалідований після PATCH-запиту.
3. Щоб уникнути помилок у ланцюжках залежних даних
Припустімо:
- /api/projects -> список проєктів,
- /api/projects/:id -> детальна сторінка проєкту.
Після оновлення одного проєкту потрібно:
- оновити його детальні дані;
- і інвалідувати список проєктів, щоб він теж оновився.
Якщо цього не зробити, у списку залишиться стара версія, навіть якщо деталі вже оновлено.
4. Щоб не накопичувалися «застарілі» кеші
Якщо кеш ніколи не інвалідувати:
- він росте безконтрольно;
- дані перестають відповідати серверу;
- застосунок стає «застряглим» у старому стані.
Це особливо критично під час тривалих сесій (SPA без перезавантаження).
Як правильно інвалідувати кеш
1. Ручна інвалідація
Після успішного POST, PATCH, PUT або DELETE потрібно сказати бібліотеці: «Ці дані застаріли, онови їх».
React Query:
import { useQueryClient } from "@tanstack/react-query";
const queryClient = useQueryClient();
async function updateUser(id, newData) {
await fetch(`/api/users/${id}`, { method: "PATCH", body: JSON.stringify(newData) });
// Invalidation
queryClient.invalidateQueries({ queryKey: ["user", id] });
queryClient.invalidateQueries({ queryKey: ["users"] }); // if the list depends on it
}React Query сам надішле повторний запит до сервера, щоб отримати свіжі дані.
2. Оптимістичне оновлення
Іноді можна оновити UI одразу, не чекаючи на відповідь від сервера.
queryClient.setQueryData(['user', id], old => ({ ...old, ...newData }));
await fetch(`/api/users/${id}`, { method: 'PATCH', body: JSON.stringify(newData) });
queryClient.invalidateQueries(['user', id]);Користувач бачить миттєвий відгук, а React Query потім тихо підвантажить актуальні дані та синхронізує їх.
3. Stale Time + Background Refetch
Якщо дані кешуються на обмежений час (staleTime), то після його завершення React Query вважає їх «застарілими» і автоматично робить повторний запит при фокусі вікна або ремаунті компонента.
useQuery({
queryKey: ['user', id],
queryFn: fetchUser,
staleTime: 5 * 60 * 1000, // 5 minutes
});Навіть якщо ти забув інвалідувати вручну, дані не будуть «вічно старими».
4. Інвалідація пов'язаних даних
Якщо в тебе, наприклад:
- /api/posts
- /api/posts/:id/comments
і користувач додає новий коментар, ти маєш інвалідувати не лише /comments, а й /posts (якщо там показується кількість коментарів).
queryClient.invalidateQueries(['comments', postId]);
queryClient.invalidateQueries(['posts']);5. SWR - аналогічний механізм
У SWR можна викликати:
import useSWR, { mutate } from 'swr';
await fetch('/api/user/1', { method: 'PATCH', body: JSON.stringify(data) });
// Invalidation
mutate('/api/user/1'); // refetch
mutate('/api/users'); // if there's a dependent listПІДСУМОК
| Причина | Що станеться без інвалідації |
|---|---|
| Дані не оновляться в UI | Користувач бачить стару інформацію |
| Неузгодженість між компонентами | Різні частини показують різні версії даних |
| Помилки в залежних запитах | Списки й деталі розходяться |
| Переповнений кеш | Пам'ять витрачається, дані неактуальні |
| Втрата довіри користувача | «Я ж змінив, чому не змінилося?» |
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.