логотип PurpleSchool
логотип PurpleSchool

Сохранение данных локально на 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). Это позволяет очищать только нужные значения без сброса всего хранилища.

Стрелочка влевоУправление config на React NativeКак работать с внешними API на React NativeСтрелочка вправо

Постройте личный план изучения React-native до уровня Middle — бесплатно!

React-native — часть карты развития Mobile

  • step100+ шагов развития
  • lessons30 бесплатных лекций
  • lessons300 бонусных рублей на счет

Бесплатные лекции

Все гайды по React-native

Работа со ScrollView в React NativeРабота с видео в React NativeКак реализовать аудиоплеер на React NativeНастройка и использование input и textinput в React NativeИнтеграция видео плеера в приложение на React NativeИспользование выпадающих списков в React NativeСоздание и настройка native module на React NativeКак создать модальные окна в React NativeРабота с изображениями в React NativeОтображение списков данных в React NativeГайд по файловой системе в React NativeИнтеграция камеры в приложение на React NativeСоздание интерактивных кнопок в React Native
Как использовать векторные иконки в React Native5 популярных библиотек UI компонентов React NativeСоздание и использование tabs в React NativeРуководство по стилизации компонентов в React NativeОптимизация переходов между экранами в React NativeАдаптация safe area context на React NativeОбзор библиотек для навигации в React NativeСоздание сложных анимаций (reanimated) на React NativeИспользование библиотеки стилей Paper в React NativeРуководство по navigation в React NativeОптимизация отображения списков в React NativeКак реализовать linking на React NativeГайд по UI-китам для React NativeГде искать elements для приложения на React NativeРабота с цветами в React Native
Открыть базу знаний

Лучшие курсы по теме

изображение курса

React Native и Expo Router

Антон Ларичев
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Основы JavaScript

Антон Ларичев
AI-тренажеры
Практика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.8
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

TypeScript с нуля

Антон Ларичев
AI-тренажеры
Практика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее

Отправить комментарий