Хранит ли состояние сайт?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Хранит ли состояние сайт?
Да, и это важный вопрос. Я много раз требования писал, где нужно хранить состояние (state) веб-приложения. Расскажу про разные варианты.
Что такое состояние (state)
Это информация, которая изменяется при использовании приложения.
Примеры:
- Корзина покупок (какие товары там, количество)
- Данные фильтра (выбранный размер, цвет)
- Информация авторизованного пользователя (кто я, какой мой баланс)
- История поиска (какие запросы я вводил)
Где можно хранить state
Вариант 1: В памяти браузера (Memory)
// Komponenta React
const [cart, setCart] = useState([]);
// Когда пользователь добавляет товар:
setCart([...cart, newItem]);
Плюсы:
- Быстро (данные в памяти, не нужно идти на сервер)
- Просто код
Минусы:
- Если обновить страницу (F5) → все потеряется
- Не сохраняется между сеансами
- Ненадежно
Когда использовать:
- Временная информация (фильтр на странице, открытый modal)
- Состояние, которое не критично потерять
- UI состояние (темная тема, sidebar открыт/закрыт)
Пример требования:
Когда пользователь выбирает фильтр (размер XL):
- Результаты обновляются без перезагрузки
- Фильтр сохраняется в памяти React
- Если обновить страницу → фильтр теряется (это OK для фильтров)
Вариант 2: Локальное хранилище браузера (LocalStorage)
// Сохранить
localStorage.setItem('cart', JSON.stringify(cart));
// Загрузить
const saved = localStorage.getItem('cart');
if (saved) {
setCart(JSON.parse(saved));
}
Плюсы:
- Сохраняется между сеансами (закрой браузер → данные останутся)
- Простой API (setItem, getItem)
- Нет запросов на сервер
Минусы:
- Максимум ~5MB данных (зависит от браузера)
- Небезопасно для sensitive данных (пароль, токены)
- Синхронный (может замедлить страницу если много данных)
Когда использовать:
- Корзина покупок (не критично если потеряется)
- История поиска
- User preferences (темная тема, язык)
- Draft сообщения (пока не отправил)
Пример требования:
Когда пользователь добавляет товар в корзину:
- Корзина сохраняется в localStorage
- Если закроет браузер и вернется → корзина восстановится
- Это не критичное хранилище (если потеряется, user может добавить заново)
ОС:
- localStorage.setItem('cart', JSON.stringify(cart))
- При загрузке: localStorage.getItem('cart')
Вариант 3: SessionStorage (для сеанса)
Похоже на localStorage, но удаляется при закрытии вкладки.
sessionStorage.setItem('temp_draft', message);
Когда использовать:
- Временные данные для одного сеанса
- Черновик формы (пока пользователь не отправил)
- Данные шага 1 формы, перед шагом 2
Вариант 4: Сервер (база данных)
Когда пользователь сохраняет что-то:
1. Frontend отправляет данные на сервер
2. Сервер сохраняет в БД
3. Данные persistent (не потеряются)
Плюсы:
- Самый надежный способ
- Доступно со всех устройств (если юзер зайдет с телефона → данные те же)
- Безопасно (на сервере, не в браузере)
- Неограниченный размер
Минусы:
- Медленнее (сетевой запрос на сервер)
- Требует разработку API
- Требует базу данных
Когда использовать:
- Все персональные данные (профиль, адреса)
- Заказы, транзакции
- Избранные товары
- Комментарии, посты
- Все, что нужно сохранить надолго
Пример требования:
Когда пользователь добавляет адрес доставки:
1. Фронт отправляет POST /api/v1/profile/addresses
2. Сервер сохраняет в БД
3. При следующем входе → адреса загружаются из БД
4. Это критичное хранилище (must не потерять)
Вариант 5: Cookies
// Сохранить
document.cookie = "user_id=123; path=/; max-age=3600";
// Загрузить
const cookies = document.cookie;
Плюсы:
- Автоматически отправляются на сервер (удобно для auth)
- Могут быть secure (HttpOnly = недоступны из JS)
- Могут иметь expiration
Минусы:
- Максимум 4KB
- Отправляются в каждом запросе (overhead)
- Не рекомендуется для больших данных
Когда использовать:
- Авторизация (токен, session ID)
- Tracking (analytics cookies)
- User preferences (если нужно на сервере)
Пример требования:
Когда пользователь логинится:
1. Сервер создает токен
2. Отправляет в браузер в cookie (HttpOnly, Secure)
3. При каждом запросе браузер автоматически отправляет cookie
4. Сервер проверяет токен
Это безопасно, потому что cookie HttpOnly (JS не может прочитать)
Комбинированный подход (рекомендую)
Обычно я использую все вместе:
FRONTEND:
- Memory (React state): UI состояние, фильтры
- LocalStorage: корзина, preferences
- Server API: все персональные данные
SERVER:
- Database: постоянные данные
- Cache (Redis): часто запрашиваемые данные
- Cookies: авторизация (HttpOnly, Secure)
Пример требования из реальной практики
Проект: интернет-магазин
СТАТИ И ГДЕ ХРАНЯТСЯ:
1. ФИЛЬТРЫ на странице поиска
- Где: Memory (React state)
- Сохраняется: в URL параметры (?size=XL&color=red)
- При обновлении страницы: восстанавливается из URL
- Критичность: LOW (не критично если потеряется)
2. КОРЗИНА ПОКУПОК
- Где: LocalStorage + Server
- Сохраняется: в localStorage для быстрого доступа
- Синхронизируется с сервером: при покупке
- Критичность: MEDIUM (хорошо если сохранится, но не критично)
3. ИСТОРИЯ ПОИСКА
- Где: LocalStorage
- Сохраняется: последние 10 поисков
- Критичность: LOW (nice-to-have)
4. ЛИЧНЫЕ ДАННЫЕ ПОЛЬЗОВАТЕЛЯ
- Где: Server (в БД)
- Сохраняется: все адреса, способы оплаты
- Синхронизируется: из сервера при загрузке страницы
- Критичность: CRITICAL (нельзя потерять)
5. АВТОРИЗАЦИЯ
- Где: Cookie (HttpOnly) + Server (session в БД)
- Сохраняется: токен в cookie, session в БД
- Критичность: CRITICAL (нельзя потерять)
6. ТЕМНАЯ ТЕМА (предпочтение)
- Где: LocalStorage
- Сохраняется: 'dark' или 'light'
- При загрузке страницы: восстанавливается
- Критичность: LOW (nice-to-have)
Реальная ошибка
Bad case
Железный магазин
Пользователь отложил товар в wishlist
Данные хранились только в localStorage
Случилось:
- Пользователь зайдет с другого браузера → wishlist пуст
- Пользователь очистил кеш браузера → wishlist пуст
- Пользователь жалуется: "Мой wishlist исчез!"
Решение:
Рейтинг wishlist на сервер (в БД)
Тогда доступно со всех браузеров и устройств
Мой чек-лист при написании требования
Для каждого состояния (state) я спрашиваю:
[ ] ЭТО важно сохранить?
YES → Server, NO → LocalStorage/Memory
[ ] НУЖНО ли это на других устройствах?
YES → Server, NO → LocalStorage OK
[ ] КРИТИЧНО ли, если потеряется?
YES → Server + Backup, NO → LocalStorage
[ ] ЛИЧНЫЕ/SENSITIVE данные?
YES → Server (encrypted), NO → LocalStorage OK
[ ] ЧАСТО МЕНЯЕТСЯ?
YES → Memory (быстро), NO → Server OK
[ ] БОЛЬШОЙ РАЗМЕР (> 5MB)?
YES → Server, NO → LocalStorage OK
Вывод
Железный магазин требование:
❌ ПЛОХО: "Сохранять состояние корзины"
✅ ХОРОШО:
Корзина хранится:
- В памяти React (быстрое отображение)
- В localStorage (если закроет браузер → восстановится)
- На сервере при checkout (синхронизация между устройствами)
Если пользователь:
- Обновит страницу → корзина восстановится из localStorage
- Зайдет с другого браузера → новая пустая корзина (это OK)
- Нажмет checkout → корзина сохранится в БД
Сос правильного хранения state экономит часы разработки и избегает потери данных пользователем.