React Native AsyncStorage — руководство по использованию и альтернативам

Важно: в статье показаны практические шаблоны, решения типичных проблем, варианты альтернатив и чек-листы для ролей команды.
Что такое AsyncStorage в React Native?
AsyncStorage — это асинхронное персистентное хранилище «ключ–значение». Оно сохраняет строки и обычно используется для сериализованных JavaScript-объектов (через JSON.stringify / JSON.parse). Данные в AsyncStorage сохраняются между запусками приложения и после перезапуска устройства, поэтому это удобное решение для локального кеша и небольшого состояния приложения.
Коротко о терминах:
- Персистентность: данные остаются после закрытия приложения.
- Сериализация: приведение объектов к строке (обычно JSON).
Почему использовать AsyncStorage — какие проблемы оно решает
До появления простого API для хранилища разработчики использовали разные способы: in-memory состояния (не сохраняется при закрытии), менее надёжные локальные хранилища или сразу полноценные базы данных (слишком тяжеловесно для простых задач). AsyncStorage предлагает баланс: простота API и персистентность без существенной сложности в настройке.
AsyncStorage удобен для:
- кеширования результатов запросов API;
- сохранения настроек пользователя;
- хранения токенов и небольшого состояния между сессиями.
Ограничения: оно не шифрует данные по умолчанию и не предназначено для крупных двоичных объектов или очень больших объёмов данных.
Установка и подключение
Установите пакет в корне проекта:
npm install @react-native-async-storage/async-storageИмпорт в коде:
import AsyncStorage from '@react-native-async-storage/async-storage';AsyncStorage работает асинхронно и возвращает промисы, поэтому рекомендуется использовать async/await или обработчики промисов.
Основные методы AsyncStorage
Ниже приведены основные операции и примеры использования.
Запись данных: setItem и multiSet
setItem(key, value) сохраняет строку по ключу. multiSet позволяет сохранить несколько пар ключ/значение за один вызов.
Пример:
// Сохранить простое значение
await AsyncStorage.setItem('user', 'john');
// Сохранить несколько значений
await AsyncStorage.multiSet([['user', 'john'], ['role', 'admin']]);Эти методы возвращают промис — он разрешается после завершения операции или отклоняется с ошибкой.
Чтение данных: getItem и multiGet
getItem возвращает строку или null, если ключа нет.
const name = await AsyncStorage.getItem('user');Если вы сохраняли JSON, то нужно распарсить:
await AsyncStorage.setItem('user', JSON.stringify({name: 'John Doe', age: 30}));
const user = JSON.parse(await AsyncStorage.getItem('user'));multiGet позволяет получить сразу несколько пар:
const pairs = await AsyncStorage.multiGet(['user', 'role']);
// pairs — массив [ [key, value], ... ]Объединение значений: mergeItem и multiMerge
mergeItem сливает новый JSON с существующим значением (если оба — сериализованные объекты). Для не-JSON значений поведение зависит от платформы и формата — обычно рекомендуется использовать JSON.
await AsyncStorage.mergeItem('profile', JSON.stringify({lastSeen: 1670000000000}));multiMerge выполняет слияние для нескольких ключей.
Важно: AsyncStorage не шифрует данные по умолчанию. Не храните чувствительную информацию без дополнительной защиты.
Удаление и очистка: removeItem и clear
removeItem удаляет один ключ, а clear — все ключи в хранилище:
await AsyncStorage.removeItem('user');
await AsyncStorage.clear();clear удаляет все пары ключ–значение и используется при выходе пользователя из аккаунта или при сбросе состояния приложения.
Обработка ошибок и устойчивость
Всегда оборачивайте вызовы AsyncStorage в try/catch. Возможны ошибки диска, ограничения платформы или переполнение квот.
try {
await AsyncStorage.setItem('user', 'john');
} catch (e) {
console.error('AsyncStorage error', e);
}Примеры использования: кеширование данных
Ниже — пример шаблона кеширования списка книг: сначала проверяем кеш, затем — API, после чего обновляем кеш.
import React, { useEffect, useState } from 'react';
import { View, Text, FlatList } from 'react-native';
import AsyncStorage from '@react-native-async-storage/async-storage';
const App = () => {
const [books, setBooks] = useState([]);
useEffect(() => {
const fetchBooks = async () => {
try {
const cachedData = await AsyncStorage.getItem('cachedBooks');
if (cachedData !== null) {
setBooks(JSON.parse(cachedData));
} else {
const response = await fetch('https://api.example.com/books');
const data = await response.json();
await AsyncStorage.setItem('cachedBooks', JSON.stringify(data));
setBooks(data);
}
} catch (error) {
console.error(error);
}
};
fetchBooks();
}, []);
return (
Book List
item.id.toString()}
renderItem={({ item }) => (
{item.title}
{item.author}
)}
/>
);
};
export default App;Этот шаблон показывает два важных принципа: сначала читаем локальный кеш, затем — сеть; и после получения данных обновляем локальный кеш.
Продвинутые паттерны
Добавление TTL (время жизни) к кешу
AsyncStorage не поддерживает TTL из коробки. Можно хранить объект с метаданными, указывающими время истечения:
const setWithTTL = async (key, value, ttlMs) => {
const record = { value, expiresAt: Date.now() + ttlMs };
await AsyncStorage.setItem(key, JSON.stringify(record));
};
const getWithTTL = async (key) => {
const raw = await AsyncStorage.getItem(key);
if (!raw) return null;
const record = JSON.parse(raw);
if (record.expiresAt && Date.now() > record.expiresAt) {
await AsyncStorage.removeItem(key);
return null;
}
return record.value;
};Конкурентный доступ и атомарность
AsyncStorage не предлагает транзакции. Для логики, где возможны коллизии, применяйте optimistic updates, блокировки на уровне приложения или используйте подспециализированные решения.
Работа с большими объёмами данных
AsyncStorage лучше подходит для небольших текстовых данных и сериализованных объектов. Для большого объёма или сложных запросов используйте базы (SQLite), серверные синхронизации или MMKV.
Альтернативы и когда их выбирать
Если AsyncStorage не подходит, рассмотрите:
- MMKV (ремарка: очень быстрый key-value, подходит для критичной производительности);
- SQLite (локальная реляционная БД, для сложных запросов и больших наборов данных);
- WatermelonDB / Realm (локальные БД с поддержкой сложной модели данных и синхронизации);
- Secure Storage (для хранения чувствительных данных, например react-native-keychain или EncryptedSharedPreferences/KeyStore на Android).
Выбор зависит от требований: объёма данных, скорости, необходимости шифрования и синхронизации.
Безопасность и соответствие требованиям конфиденциальности
AsyncStorage не шифрует данные по умолчанию. Для хранения токенов и паролей используйте безопасные хранилища. При обработке персональных данных соблюдайте местные правила защиты данных (например, GDPR): минимизируйте хранимые персональные данные, шифруйте их и обеспечьте процедуру удаления по запросу пользователя.
Решения для типичных проблем (Troubleshooting)
- Нечитаемые данные / парсинг JSON — проверьте, что вы сохраняете корректную JSON-строку.
- Потеря данных после обновления приложения — удостоверьтесь, что ключи не изменяются и обновления миграций выполняются корректно.
- Медленная работа при массовых операциях — используйте batch-операции (multiSet/multiGet) или мигрируйте в более производительное решение.
Рекомендации по миграции данных
Если вы меняете структуру сохранённых объектов, используйте версионирование схемы в хранилище и миграционные скрипты при старте приложения:
const migrate = async () => {
const version = await AsyncStorage.getItem('schemaVersion');
if (!version) {
// выполнить миграцию с версии 0 => 1
// пример: переименование ключей, преобразование форматов
await AsyncStorage.setItem('schemaVersion', '1');
}
};Decision flow: нужно ли использовать AsyncStorage? (Mermaid)
flowchart TD
A[Нужна локальная персистентность?] -->|Нет| B[Не нужно AsyncStorage]
A -->|Да| C[Данные небольшие и не чувствительные?]
C -->|Да| D[Использовать AsyncStorage]
C -->|Нет| E[Нужна безопасность или объём => Использовать SecureStorage/MMKV/SQLite]
D --> F[Использовать TTL/версионирование при необходимости]Чек-листы по ролям
Разработчик:
- проверить, какие данные будут храниться и нужны ли они между сессиями;
- обернуть все вызовы в try/catch;
- применять JSON.stringify/parse для комплексных объектов;
- добавить версионирование схемы и миграции.
QA:
- тестировать восстановление данных после перезапуска приложения;
- проверять сценарии очистки кеша и логаут;
- тестировать поведение при повреждённых данных (невалидный JSON).
Product Manager:
- определить, какие данные действительно нужно хранить локально;
- учитывать требования безопасности и соответствия законам о данных;
- согласовать стратегию кеширования и время жизни данных.
Шаблон (playbook) для внедрения AsyncStorage в проект
- Инвентаризация: перечислить все типы данных, которые предполагается сохранять.
- Классификация: разделить данные на чувствительные/нешифруемые, критичные/временные.
- Выбор стратегии: AsyncStorage для простых данных, SecureStorage для секретов, БД для больших наборов.
- Имплементация: утилиты get/set с обработкой ошибок и TTL.
- Миграции: добавить schemaVersion и миграционные шаги.
- Мониторинг: логирование ошибок хранилища и метрик (например, частота обращений).
Шпаргалка (cheat sheet)
- Установка: npm install @react-native-async-storage/async-storage
- Импорт: import AsyncStorage from ‘@react-native-async-storage/async-storage’
- Сохранить: await AsyncStorage.setItem(‘key’, JSON.stringify(value))
- Получить: const value = JSON.parse(await AsyncStorage.getItem(‘key’))
- Удалить: await AsyncStorage.removeItem(‘key’)
- Очистить всё: await AsyncStorage.clear()
- Массово: await AsyncStorage.multiSet([[k1,v1],[k2,v2]]) / await AsyncStorage.multiGet([k1,k2])
Примеры тест-кейсов / критерии приёмки
- Данные сохраняются и доступны после перезапуска приложения.
- При сохранении некорректного JSON приложение не падает: ошибка обрабатывается.
- При очистке (clear) все ключи удаляются.
- Миграция схемы сохраняет данные в корректном формате и не теряет критичные поля.
Когда AsyncStorage может не подойти (контрпример)
- Нужно хранить большие двоичные файлы (изображения, видео).
- Необходима сложная индексация и запросы по данным.
- Нужно гарантирующее шифрование и безопасное хранение секретов без дополнительной библиотеки.
В таких случаях лучше выбрать специализированные решения.
Краткое резюме
AsyncStorage — удобное и простое решение для локального хранения небольших данных в React Native. Оно отлично подходит для кеширования, настроек и временного состояния, но не заменяет полноценные базы данных или зашифрованные хранилища для секретов. Используйте строгие шаблоны (TTL, миграции, обработка ошибок) и выбирайте альтернативы, если ваши требования выходят за рамки простого key-value хранилища.
Помните: безопасность и масштабируемость должны определять выбор хранилища.
Похожие материалы
Google 3D животные: как просматривать в AR
Таймлапс на ESP32-CAM: полное руководство
Как купить истёкший домен и победить на аукционе
Солнечное USB‑зарядное своими руками
Кастомные функции в Google Sheets