localStorage в React — сохранить данные в браузере

localStorage хранит данные в браузере и сохраняет их после перезагрузки страницы. В React его часто используют для темы, черновиков формы, простых настроек и небольших локальных списков.

Работа с localStorage в JavaScript

Прежде чем подключать localStorage к React, полезно понять его обычный браузерный API. Это простое key-value-хранилище, но оно хранит только строки, не умеет само обновлять интерфейс и не защищает данные от JavaScript-кода страницы.

Когда базовые команды понятны отдельно от React, проще не путать две задачи: браузер хранит строку, а React отвечает за состояние интерфейса. Ошибки обычно появляются именно на смешении этих уровней.

Базовые команды

localStorage.setItem('theme', 'dark');
const theme = localStorage.getItem('theme');
localStorage.removeItem('theme');
localStorage.clear();

Объекты через JSON

const user = { name: 'Алиса', age: 25 };
localStorage.setItem('user', JSON.stringify(user));

const saved = localStorage.getItem('user');
const parsed = saved ? JSON.parse(saved) : null;

localStorage внутри React-компонента

В React localStorage почти всегда связывают с состоянием компонента: сначала читают начальное значение, затем сохраняют изменения. Главная задача — не читать хранилище на каждом рендере и не хранить там то, что должно жить на сервере.

Хороший React-код не обращается к localStorage хаотично. Чтение лучше делать один раз при инициализации, запись — при изменении значения, а общую логику удобно вынести в небольшой кастомный хук.

localStorage и useState

import { useEffect, useState } from 'react';

function ThemeToggle() {
  const [theme, setTheme] = useState(() => {
    return localStorage.getItem('theme') || 'light';
  });

  useEffect(() => {
    localStorage.setItem('theme', theme);
    document.documentElement.dataset.theme = theme;
  }, [theme]);

  return (
    <button onClick={() => setTheme(t => t === 'light' ? 'dark' : 'light')}>
      Тема: {theme}
    </button>
  );
}

Кастомный хук useLocalStorage

import { useEffect, useState } from 'react';

function useLocalStorage(key, defaultValue) {
  const [value, setValue] = useState(() => {
    const saved = localStorage.getItem(key);
    if (saved === null) return defaultValue;

    try {
      return JSON.parse(saved);
    } catch {
      return defaultValue;
    }
  });

  useEffect(() => {
    localStorage.setItem(key, JSON.stringify(value));
  }, [key, value]);

  return [value, setValue];
}

Использование hook

function Notes() {
  const [notes, setNotes] = useLocalStorage('notes', []);

  function addNote(text) {
    setNotes(prev => [...prev, { id: Date.now(), text }]);
  }

  return notes.map(note => <p key={note.id}>{note.text}</p>);
}

Ограничения

  • localStorage хранит только строки.
  • Объём ограничен примерно несколькими мегабайтами на домен.
  • API синхронный, большие записи могут тормозить интерфейс.
  • Не храните токены и пароли, доступные JavaScript.
  • В SSR localStorage нет на сервере, обращаться можно только на клиенте.

Хранение с TTL

У localStorage нет срока жизни. Если нужно, чтобы данные протухали, сохраните вместе со значением время истечения.

function setWithTtl(key, value, ttlMs) {
  const item = {
    value,
    expiresAt: Date.now() + ttlMs,
  };
  localStorage.setItem(key, JSON.stringify(item));
}

function getWithTtl(key) {
  const raw = localStorage.getItem(key);
  if (!raw) return null;

  const item = JSON.parse(raw);
  if (Date.now() > item.expiresAt) {
    localStorage.removeItem(key);
    return null;
  }

  return item.value;
}

Где localStorage уместен, а где нет

localStorage удобен для небольших пользовательских настроек, но его легко переоценить. Он не заменяет базу данных, не защищает секреты и не подходит для больших объёмов данных.

Ориентир такой: localStorage подходит для данных, потеря которых не разрушит сценарий пользователя. Всё, что связано с авторизацией, оплатой, персональными данными или важной бизнес-логикой, должно храниться на сервере или в более защищённом механизме.

Хорошие сценарии

  • тема интерфейса: светлая или тёмная;
  • черновик формы, который жалко потерять при перезагрузке;
  • последний выбранный фильтр или вкладка;
  • небольшой список локальных заметок;
  • флаг, что пользователь уже закрыл подсказку.

Где localStorage опасен

Не храните в localStorage пароли, приватные токены, ключи API и чувствительные персональные данные. Всё, что лежит в localStorage, доступно JavaScript-коду страницы, а значит становится целью при XSS-уязвимости.

Простая проверка перед использованием

Спросите себя: если пользователь очистит браузер, данные можно потерять без катастрофы? Если да, localStorage подходит. Если нет, данные должны жить на сервере.

Оцените статью
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
0
Оставьте комментарий! Напишите, что думаете по поводу статьи.x