Почти каждое сложное фронтенд-приложение ломается не из-за одного большого хранилища состояния, а из-за путаницы между локальным состоянием, серверным состоянием, состоянием в URL, состоянием формы и инвалидацией кэша. Чем раньше эти контуры становятся явными, тем меньше хаоса возникает при обновлении интерфейса и расследовании багов.
Эта глава связывает управление состоянием с реальными сценариями: оптимистичными обновлениями, фоновым обновлением, очередью действий без сети, обновлениями в реальном времени и возвратом пользователя на предыдущий экран. Она помогает обсуждать состояние как несколько классов данных с разным временем жизни, а не как одну универсальную корзину.
Для архитектурного ревью и интервью материал даёт способ честно говорить о главной боли фронтенда: где проходит источник истины, кто владеет кэшем и почему инвалидация обычно труднее первого запроса.
Практическая польза главы
Практика проектирования
Разделяйте состояние по времени жизни и источнику истины: локальное, серверное, состояние в URL и состояние формы не должны жить по одним правилам.
Качество решений
Оценивайте решение по свежести данных, стратегии инвалидации, откату оптимистичных обновлений и поведению при повторном подключении.
Аргументация на интервью
Стройте ответ как цепочку: класс состояния, владелец, место хранения, правило обновления, кэш и поведение при сбое.
Формулировка компромиссов
Фиксируйте цену выбора: простота локального состояния, переиспользование кэша, риск устаревших данных и сложность синхронизации.
Контекст
Стратегии кэширования
Во фронтенде инвалидация кэша так же сложна, как на серверной стороне: пользователь видит каждую ошибку прямо на экране.
Почти в каждом сложном фронтенд-приложении спор об управлении состоянием на самом деле оказывается спором о том, какие классы состояния смешали в одну корзину. Локальное состояние интерфейса, серверное состояние, состояние в URL и состояние формы живут по-разному и ломаются по-разному.
Поэтому ключевой вопрос звучит так: где находится источник истины и кто отвечает за инвалидацию после пользовательского действия, фонового обновления или события в реальном времени.
В этой главе раскладывается на , , и . Мы связываем это с , , , , , и .
Карта состояния и кэша
Один экран одновременно держит локальное состояние, форму, параметры URL и копию серверных данных. Переключайте сценарии, чтобы увидеть, где живёт состояние и кто отвечает за его обновление.
Где живёт состояние
Схема разделяет состояние по владельцу: что держит экран, что кодируется в URL, что хранится в кэше запросов и что подтверждает сервер.
Вход
Маршрут и экран
URL, параметры маршрута и видимый экран задают контекст пользовательского сценария.
Рядом с UI
Локальное состояние
Модалки, hover, раскрытые панели и временные черновики лучше держать рядом с компонентом.
Сериализация
Форма и URL
Поля формы, признаки несохранённых изменений, фильтры и пагинация живут по отдельным правилам.
Копия данных
Кэш запросов
Кэш хранит клиентскую копию серверных данных, их свежесть и правила инвалидации.
Источник истины
Сервер
Сервер подтверждает факты, применяет мутации и возвращает новое согласованное состояние.
События
Realtime-канал
WebSocket или push-события приносят внешние изменения, которые нужно слить с локальным экраном.
Архитектурный смысл
Главная граница
- Не всё состояние должно попадать в глобальное хранилище.
- Кэш запросов не является источником истины, а только управляемой копией.
- URL и форма требуют явных правил сериализации, восстановления и очистки.
Классы состояния
Локальное состояние интерфейса
Видимость модального окна, наведение, временные фрагменты черновика и состояние текущего взаимодействия. Такое обычно живет рядом с компонентом и не требует глобальной синхронизации.
Серверное состояние
Профиль, элементы ленты, виджеты дашборда и заказы, для которых находится на серверной стороне. Их поведение задают , и .
Состояние в URL
Фильтры, курсор пагинации, активные вкладки и поисковые параметры. Если пользователь ожидает или восстановление после обновления страницы, это должно быть сериализуемым.
Состояние формы
Валидация, , , ошибки на уровне полей и оптимистичная отправка. почти всегда живет по отдельным правилам, отличным от обычного кэша запросов.
Связано
Фронтенд-кейс: коллаборативный редактор в стиле Google Docs
Совместное редактирование быстро показывает, насколько дорого обходятся неявные правила слияния и отката.
Паттерны обновления и инвалидации
Оптимистичное обновление с явным откатом
Подходит для действий, где намерение пользователя очевидно: лайк, переименование, переключатель. Главное - заранее определить, как интерфейс объяснит конфликт или выполнит .
Фоновая проверка актуальности
Работает для экранов, где допустимы слегка устаревшие данные: сначала показываем , затем тихо сверяемся с сервером и обновляем только изменившиеся зоны.
Точная инвалидация по доменным ключам
Вместо очистки всего кэша лучше инвалидировать только группы запросов, зависящие от измененного ресурса. Такая снижает лишние сетевые запросы и визуальные скачки интерфейса.
Правила слияния обновлений в реальном времени
Обновления через WebSocket или push-канал должны иметь с локальными изменениями. Иначе интерфейс начнет прыгать между локальной и удаленной версиями.
Частые антипаттерны
- Одно для всего приложения без различия между и состоянием интерфейса.
- Скрытые побочные эффекты в , которые трудно объяснить и протестировать.
- Сброс при каждой смене маршрута, из-за чего приложение постоянно теряет контекст пользователя.
- Отсутствие явной стратегии для , отката оптимистичного обновления и после сетевого сбоя.
Практическое правило
Связанные главы
- Стратегии кэширования: Cache-Aside, Read-Through, Write-Through, Write-Back - дает системный фон для , и стоимости промахов.
- Слой данных во фронтенде: REST, GraphQL, BFF и оркестрация - объясняет, какие контракты и транспортные границы определяют поведение .
- Frontend system design кейс: Design Instagram Feed - показывает состояние и кэширование в ленте с высокой долей чтения, и пагинацией.
- Фронтенд-кейс: коллаборативный редактор в стиле Google Docs - углубляет тему синхронизации в реальном времени, и после повторного подключения.
- Протокол WebSocket - важен для событийных изменений состояния, правил слияния и .
