localStorage хранит данные в браузере и сохраняет их после перезагрузки страницы. В React его часто используют для темы, черновиков формы, простых настроек и небольших локальных списков.
- Работа с localStorage в JavaScript
- Базовые команды
- Объекты через JSON
- localStorage внутри React-компонента
- localStorage и useState
- Кастомный хук useLocalStorage
- Использование hook
- Ограничения
- Хранение с TTL
- Где localStorage уместен, а где нет
- Хорошие сценарии
- Где 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 подходит. Если нет, данные должны жить на сервере.



