Олег Марков
Сохранение данных локально на React Native
Введение
В мобильной разработке часто возникает необходимость сохранять данные локально на устройстве пользователя – будь то пользовательские настройки, результаты ввода, кэш для offline-режима или даже небольшие базы данных. React Native, популярный инструмент для создания кроссплатформенных мобильных приложений, не предоставляет единого решения для хранения данных из коробки, но обладает целым набором инструментов и библиотек для этой задачи. В этой статье вы узнаете, какие альтернативы доступны для сохранения данных локально в приложениях на React Native, сравните их, увидите примеры кода и сможете подобрать наиболее подходящее решение под свои задачи.
Локальное хранение данных необходимо для сохранения состояния приложения, пользовательских настроек или временных данных. React Native предоставляет различные способы локального хранения данных, включая AsyncStorage, Realm и SQLite. Чтобы эффективно использовать локальное хранилище, необходимо понимать особенности каждого подхода и выбирать подходящий для ваших нужд. Если вы хотите детально разобраться в локальном хранении данных на React Native и создавать приложения, которые сохраняют данные между сессиями — приходите на наш большой курс React Native и Expo Router. На курсе 184 уроков и 11 упражнений, AI-тренажеры для безлимитной практики с кодом и задачами 24/7, решение задач с живым ревью наставника, еженедельные встречи с менторами.
Почему важно хранить данные локально
Многие мобильные приложения должны работать даже при отсутствии интернет-соединения. Для этого важно обеспечивать надёжное хранение части данных прямо на устройстве пользователя. К примеру:
- Локальные настройки и предпочтения пользователя
- Кэширование данных для offline-работы и ускоренного доступа
- Незавершённые заказы или формы, которые пользователь может отправить позже
- Авторизационные токены для автоматического входа при следующем запуске
- Меньшая нагрузка на серверы и трафик
На Android и iOS используются разные подходы к хранению данных, но благодаря React Native вы можете выбирать подходящие способы для обеих платформ.
Варианты локального хранения данных в React Native
Давайте рассмотрим основные подходы, которые чаще всего используют разработчики.
AsyncStorage – ключ-значение просто и быстро
AsyncStorage была стандартной встроенной библиотекой React Native для хранения данных в формате «ключ-значение». С недавних пор она вынесена в отдельный пакет (@react-native-async-storage/async-storage
). Она отлично подходит для небольшого объёма, не очень чувствительных или критичных к безопасности данных.
Установка
npm install @react-native-async-storage/async-storage
# или
yarn add @react-native-async-storage/async-storage
Использование
Смотрите, как просто организовать сохранение и чтение данных:
import AsyncStorage from '@react-native-async-storage/async-storage';
// Сохранить значение
const storeData = async (key, value) => {
try {
await AsyncStorage.setItem(key, value); // Ключ и значение должны быть строками
} catch (e) {
// Обработка ошибки при сохранении
console.error('Ошибка сохранения:', e);
}
};
// Прочитать значение
const getData = async (key) => {
try {
const value = await AsyncStorage.getItem(key);
if(value !== null) {
// Здесь можно использовать value
console.log('Значение из AsyncStorage:', value);
}
return value;
} catch(e) {
// Обработка ошибки при чтении
console.error('Ошибка чтения:', e);
}
};
Особенности и ограничения
- AsyncStorage не предназначена для больших объёмов данных
- Все значения преобразуются в строки (при необходимости используйте
JSON.stringify
) - Данные некриптованы, то есть хранятся в открытом виде
- Поддерживает только асинхронный API
SQLite – когда нужно больше, чем просто ключ-значение
Если вы строите приложение с данными, похожими на реляционную базу, например, списком задач, пользователей, заметок — вам может подойти SQLite. Это встроенная СУБД, поддерживаемая как на Android, так и на iOS.
Для React Native есть несколько популярных обёрток. Самая популярная — react-native-sqlite-storage
.
Установка
npm install react-native-sqlite-storage
# или
yarn add react-native-sqlite-storage
Не забудьте выполнить линковку для корректной установки на обеих платформах.
Пример использования
Здесь я показываю пример создания таблицы и работы с ней:
import SQLite from 'react-native-sqlite-storage';
// Открываем (или создаём) базу данных
const db = SQLite.openDatabase(
{ name: 'mydb.db', location: 'default' },
() => { console.log('База данных открыта'); },
error => { console.log('Ошибка открытия БД:', error); }
);
// Создадим таблицу пользователей
db.transaction(tx => {
tx.executeSql(
'CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, age INTEGER);'
);
});
// Добавление пользователя
const addUser = (name, age) => {
db.transaction(tx => {
tx.executeSql(
'INSERT INTO users (name, age) VALUES (?, ?);',
[name, age], // параметризованные значения
(tx, results) => {
console.log('Результат вставки:', results);
}
);
});
};
// Получение всех пользователей
const getUsers = (callback) => {
db.transaction(tx => {
tx.executeSql(
'SELECT * FROM users;',
[],
(tx, results) => {
let users = [];
for (let i = 0; i < results.rows.length; ++i) {
users.push(results.rows.item(i));
}
callback(users); // Возвращаем список пользователей
}
);
});
};
Особенности
- Full-text search и сложные запросы
- Позволяет реализовать полноценную offline-first логику
- Вы сами управляете структурой данных и оптимизируете запросы
- База данных физически хранится в пределах приложения
MMKV – быстрое key-value хранилище от WeChat
Если вам важно быстрое сохранение и доступ к данным, обратите внимание на MMKV — высокопроизводительное key-value хранилище от разработчиков WeChat.
Установка
npm install react-native-mmkv
# или
yarn add react-native-mmkv
Использование
Примерно так организуется работа с MMKV:
import { MMKV } from 'react-native-mmkv';
// Создаем экземпляр MMKV
const storage = new MMKV();
// Сохраняем значение
storage.set('user_token', 'abcdef123456');
// Получаем значение
const token = storage.getString('user_token'); // Вернет строку или undefined
// Удаляем значение
storage.delete('user_token');
Преимущества
- Феноменальная скорость (особенно на Android)
- Автоматическая сериализация/десериализация JSON
- Простота интеграции
Недостатки
- Только key-value API, нет сложной структуры как у SQLite
- Не предназначено для truly secure storage
Secure Storage – для хранения чувствительных данных
Если вы хотите хранить пароли, токены доступа и прочие критичные к безопасности значения, используйте secure storage. Самый распространённый пакет для этого — react-native-keychain
.
Установка
npm install react-native-keychain
# или
yarn add react-native-keychain
Пример сохранения токена
import * as Keychain from 'react-native-keychain';
// Сохраняем логин и пароль
await Keychain.setGenericPassword('myUsername', 'myPassword');
// Получаем сохранённые данные
const credentials = await Keychain.getGenericPassword();
if (credentials) {
console.log('Данные:', credentials.username, credentials.password);
} else {
console.log('Нет сохранённых данных');
}
// Удаляем сохранённые данные
await Keychain.resetGenericPassword();
Особенности
- Использует Keychain (iOS) и Encrypted Shared Preferences (Android)
- Работает только с небольшими объёмами данных (строки/ключи)
- Отлично подходит для хранения пользовательских токенов и паролей
Работа с файлами
В некоторых случаях необходимо сохранять целые файлы (изображения, PDF и т.д.) либо работать с файловой системой напрямую. Для этого существует библиотека react-native-fs
.
Установка
npm install react-native-fs
# или
yarn add react-native-fs
Пример записи файла
import RNFS from 'react-native-fs';
// Путь к файлу
const path = RNFS.DocumentDirectoryPath + '/myfile.txt';
// Запись строки в файл
RNFS.writeFile(path, 'Пример текста для сохранения', 'utf8')
.then(() => {
console.log('Файл успешно сохранён!');
})
.catch(err => {
console.log('Ошибка при сохранении файла:', err.message);
});
// Чтение файла
RNFS.readFile(path, 'utf8')
.then(contents => {
console.log('Содержимое файла:', contents);
});
Особенности
- Можно сохранять любые типы файлов
- Подходит для загрузки и кэширования мультимедиа
Реализация типичных задач
Сохранение и чтение сложных объектов
AsyncStorage и MMKV принимают только строки, так что для сохранения JavaScript-объектов используйте JSON.stringify
:
// Сохраняем объект
const userProfile = {name: 'Иван', age: 22};
await AsyncStorage.setItem('profile', JSON.stringify(userProfile));
// Читаем объект
const jsonString = await AsyncStorage.getItem('profile');
const user = jsonString ? JSON.parse(jsonString) : null;
// Теперь user – обычный JS-объект
Проверка токена при запуске приложения
Разрешите мне продемонстрировать, как реализовать автоавторизацию через сохранённый токен:
import AsyncStorage from '@react-native-async-storage/async-storage';
const checkToken = async () => {
const token = await AsyncStorage.getItem('auth_token');
if (token) {
// Пользователь авторизован
} else {
// Показать экран логина
}
};
Очистка всех данных при выходе
Часто требуется сбросить все локальные данные при выходе пользователя из аккаунта:
// Для AsyncStorage
await AsyncStorage.clear();
// Для MMKV
storage.clearAll();
Лучшие практики безопасности и производительности
- Не храните чувствительные данные в открытом виде. Для паролей используйте secure storage.
- Не используйте локальное хранилище в качестве базы долгосрочных данных для критичных бизнес-процессов – обновления или удаление приложения могут привести к потере данных.
- Проверяйте обратную совместимость: миграции между версиями схемы хранения могут потребовать преобразований.
- Используйте асинхронные API, чтобы не блокировать главный поток приложения.
Тестирование локального хранения данных
- Используйте заглушки или мок-реализации (например, jest mocks), чтобы тестировать логику работы, не записывая данные на устройство.
- Регулярно проверяйте, что данные корректно удаляются, особенно при тестировании выхода из аккаунта.
Заключение
React Native предлагает обширный набор инструментов для локального хранения данных — от простых ключ-значение хранилищ до полноценных реляционных баз и безопасных хранилищ для чувствительной информации. Для каждого сценария есть оптимальное решение — выбор подхода должен опираться на требования к объему и типу данных, а также на безопасность и скорость доступа. Выбирайте механизмы хранения данных осознанно, чтобы обеспечить быстрое, стабильное и безопасное взаимодействие пользователя с вашим приложением как онлайн, так и офлайн.
Локальное хранение данных - это важный аспект разработки современного React Native приложения. Однако, для создания полноценного приложения необходимо освоить множество других технологий и подходов, включая работу с UI, данными и нативными функциями. Курс React Native и Expo Router поможет вам в этом. В первых 3 модулях уже доступно бесплатное содержание — начните погружаться в мир React Native прямо сегодня.
Частозадаваемые технические вопросы по теме
Как мигрировать данные из AsyncStorage в MMKV (или наоборот)?
Чтобы мигрировать данные, прочитайте все нужные значения из старого хранилища (например, через AsyncStorage.getAllKeys()
+ multiGet()
), затем сохраните их в новое хранилище через MMKV.set()
. После успешной миграции можно очистить старое хранилище. Код для миграции может выглядеть так:
const keys = await AsyncStorage.getAllKeys();
const pairs = await AsyncStorage.multiGet(keys);
pairs.forEach(([key, value]) => {
if (value !== null) storage.set(key, value);
});
await AsyncStorage.clear(); // После успешной миграции!
Как ограничить размер хранимых данных в AsyncStorage или MMKV?
Нет встроенного лимита, но рекомендуется хранить объёмы не превышающие 2-5 МБ. Для больших данных используйте файловую систему или SQLite. Если вы не уверены в размере, сохраняйте только нужные данные и регулярно очищайте старое.
Как обеспечить синхронизацию хранения при обновлениях приложения?
При изменении структуры данных добавляйте версионирование (например, храните версию схемы в AsyncStorage). При изменении структуры — проверяйте версию и выполняйте миграцию данных (например, дополняйте или меняйте поля объектов).
Можно ли использовать несколько хранилищ в одном проекте?
Да, их совместное использование распространено. Например, MMKV для быстрых настроек, SQLite для сложных данных, Keychain для токенов. Хранилища изолированы друг от друга, так что интеграция не вызывает конфликтов.
Как удалить данные только по определённому ключу, не очищая всё локальное хранилище?
И в AsyncStorage, и в MMKV реализованы методы удаления по ключу: AsyncStorage.removeItem(key)
или storage.delete(key)
. Это позволяет очищать только нужные значения без сброса всего хранилища.
Постройте личный план изучения React-native до уровня Middle — бесплатно!
React-native — часть карты развития Mobile
100+ шагов развития
30 бесплатных лекций
300 бонусных рублей на счет
Бесплатные лекции
Все гайды по React-native
Лучшие курсы по теме

React Native и Expo Router
Антон Ларичев
Основы JavaScript
Антон Ларичев