← Назад к вопросам

Хранит ли состояние сайт?

1.0 Junior🔥 81 комментариев
#Soft Skills и личные качества

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Хранит ли состояние сайт?

Да, и это важный вопрос. Я много раз требования писал, где нужно хранить состояние (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 экономит часы разработки и избегает потери данных пользователем.