You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在基于Expo的React Native应用中本地存储大量数据(含图片)?

Best Local Storage Solutions for Large Data in Expo React Native Apps

Hey Brandon, totally get the frustration with AsyncStorage's 6MB limit—especially when you're dealing with images and form data that add up quickly. Since you're already using Expo FileSystem, let's start by optimizing that approach, then cover other robust options for large-scale local storage:

1. Optimize Your Existing Expo FileSystem Workflow

You mentioned storing images as base64 in text documents, but base64 adds ~30% extra file size compared to raw binary. A better approach is to save images directly as their original file format (JPG/PNG) to the device's storage, then store just the file URI alongside your form data (in AsyncStorage or another lightweight store). This avoids the base64 bloat and leverages FileSystem's unlimited space (well, limited only by the device's storage capacity).

Here's a quick example of how to copy an image to the app's document directory and save its URI:

import * as FileSystem from 'expo-file-system';

const saveFormWithImage = async (formData, imageUri) => {
  // Generate a unique filename for the image
  const imageFileName = `form_image_${Date.now()}.jpg`;
  const destinationUri = `${FileSystem.documentDirectory}${imageFileName}`;

  // Copy the image to the app's persistent document directory
  await FileSystem.copyAsync({
    from: imageUri,
    to: destinationUri
  });

  // Store form data + image URI (you can use AsyncStorage here for small metadata)
  const combinedData = {
    ...formData,
    imageUri: destinationUri
  };

  await FileSystem.writeAsStringAsync(
    `${FileSystem.documentDirectory}form_${Date.now()}.json`,
    JSON.stringify(combinedData)
  );
};

This keeps your image files lean and your metadata manageable.

2. Realm Database (NoSQL for Complex Data)

Realm is a high-performance, local NoSQL database that’s perfect if you need to manage structured, relational data alongside large blobs (like images). It has no hard size limits (beyond device storage) and offers fast querying capabilities—way more powerful than AsyncStorage for complex app states.

To use it in Expo, install the realm package and define a schema that supports binary data:

import Realm from 'realm';

// Define a schema for your form data
const FormDataSchema = {
  name: 'FormData',
  properties: {
    id: 'string',
    fields: 'string', // Store form fields as a JSON string
    image: 'data?' // "data" type handles binary image blobs
  },
  primaryKey: 'id'
};

// Initialize Realm and save your data
const saveFormToRealm = async (formId, formFields, imageBlob) => {
  const realm = await Realm.open({ schema: [FormDataSchema] });
  
  realm.write(() => {
    realm.create('FormData', {
      id: formId,
      fields: JSON.stringify(formFields),
      image: imageBlob
    });
  });
  
  realm.close();
};

Realm is great if you need to filter, sort, or update form data frequently.

3. Expo SQLite (Relational Database Option)

If you prefer working with SQL, Expo’s expo-sqlite package gives you access to a full SQLite database on the device. It supports BLOB columns for storing image data, making it a solid choice for structured data that needs complex queries.

Here’s a quick setup example:

import * as SQLite from 'expo-sqlite';

// Open or create a database
const db = SQLite.openDatabase('app_forms.db');

// Create a table on app load
db.transaction(tx => {
  tx.executeSql(`
    CREATE TABLE IF NOT EXISTS forms (
      id TEXT PRIMARY KEY,
      form_data TEXT,
      image BLOB
    )
  `);
});

// Insert form data with an image blob
const insertFormToSQLite = (formId, formData, imageBlob) => {
  db.transaction(tx => {
    tx.executeSql(
      'INSERT INTO forms (id, form_data, image) VALUES (?, ?, ?)',
      [formId, JSON.stringify(formData), imageBlob],
      (_, result) => console.log('Form saved!'),
      (_, error) => console.error('Save failed:', error)
    );
  });
};

This is ideal if you’re comfortable with SQL and need to handle relational data between forms or other app entities.

4. SecureStore (For Encrypted Sensitive Data)

If your form data includes sensitive information, Expo’s expo-secure-store is a better choice than AsyncStorage for encryption—but note it has small size limits per entry (usually ~2KB). Pair it with FileSystem: store encrypted form metadata in SecureStore, and save images to FileSystem, using SecureStore to keep track of encrypted file URIs or encryption keys if needed.

Final Recommendation

For your use case (form data + images), optimizing Expo FileSystem is the simplest and most efficient first step—you’re already using it, and ditching base64 will immediately save space and avoid AsyncStorage limits. If you need to manage more complex data relationships later, Realm or SQLite are excellent upgrades.

内容的提问来源于stack exchange,提问作者Brandonjgs

火山引擎 最新活动