В чем разница между кэшем и состоянием?
Что проверяют
Различаете ли вы данные, которыми владеет клиент, и копию данных сервера. Следом обычно спрашивают, где держать список заказов, пришедший с API: в Redux, в useState или в TanStack Query.
Как отвечать
Главный критерий: где источник истины.
- состояние: данные, которыми владеет само приложение. Открыта ли модалка, что введено в форму, какая вкладка выбрана. Кроме клиента их никто не знает, потеряли их, значит пользователь потерял работу;
- кэш: локальная копия данных, чей источник истины на сервере. Он может устареть, и его можно выбросить в любой момент: приложение станет медленнее, но не сломается.
Полезная проверка: «что случится, если стереть это значение?». Данные просто перезапросятся, значит это кэш. Пропадёт ввод пользователя, значит состояние.
На практике это деление на client state и server state. Для первого хватает useState, useReducer, Zustand или Redux. Для второго есть библиотеки, которые решают задачи кэша: TanStack Query, SWR, RTK Query, Apollo Client. В TanStack Query у запроса есть staleTime (по умолчанию 0, данные сразу считаются устаревшими и перезапрашиваются при монтировании и фокусе окна) и gcTime (5 минут, после чего неиспользуемая запись удаляется). После мутации кэш сбрасывают через invalidateQueries.
Есть и другие уровни: HTTP-кэш браузера по Cache-Control и ETag, Service Worker, CDN. Ими управляют заголовками и стратегией, а не кодом компонентов.
Где спотыкаются
Копируют ответ API в глобальный стор и синхронизируют его руками. Появляются дубли, забытые обновления после мутаций и самописная логика загрузки, которую библиотеки кэша уже решили.
Хранят в состоянии то, что вычисляется. Отфильтрованный список лучше получать из исходных данных при рендере, а не держать отдельной копией, которая разойдётся с оригиналом.
Говорят «кэшем управляет браузер, а состоянием разработчик». Кэш серверных данных в SPA целиком ваша ответственность: когда считать его устаревшим и когда сбрасывать.