Skip to content

A highly extensible and configurable storage engine for Redux Persist using Expo FileSystem for persistence in React Native applications.

License

Notifications You must be signed in to change notification settings

dennzimm/redux-persist-expo-file-system-storage

Repository files navigation

redux-persist-expo-file-system-storage

A highly extensible and configurable storage engine for Redux Persist using Expo FileSystem for persistence in React Native applications.

Check out my article for a quick overview and insights about this package here!

Table of Contents

Why Choose redux-persist-expo-file-system-storage?

This package serves as an alternative to the default AsyncStorage, specifically addressing storage size limitations in Android environments (#199). It offers a versatile and efficient solution for managing and persisting state in your React Native applications.

Features

  • Written in TypeScript: Complete TypeScript support for improved type safety and development experience.

  • Extensibility: Designed to be easily extended with options for customizing storage behavior through various callbacks.

  • Configurability: Fine-tune the storage engine with a variety of options, making it adaptable to different project requirements.

  • Debug Mode: Enable the debug mode for detailed logs during development, helping you troubleshoot and understand the library's actions.

  • Custom Logging: Utilize your own logger functions for debug and error messages, allowing seamless integration with your application's logging strategy.

Installation

Choose your preferred package manager and add redux-persist-expo-file-system-storage to your React Native project:

npm install redux-persist-expo-file-system-storage
yarn add redux-persist-expo-file-system-storage
pnpm add redux-persist-expo-file-system-storage
bun add redux-persist-expo-file-system-storage

After installation, you're ready to integrate the storage engine into your Redux setup for seamless state persistence.

Usage

Here's a simple example demonstrating how to integrate redux-persist-expo-file-system-storage into your application:

import * as FileSystem from "expo-file-system";
import {
  createExpoFileSystemStorage,
  type StorageOptions,
} from "redux-persist-expo-file-system-storage";
import type { PersistConfig } from "redux-persist";
import { rootReducer, type RootState } from "./store.config";

// Either without custom options (Default values can be found in the Options section)
export const expoFileSystemStorage = createExpoFileSystemStorage();

// or with custom options
export const expoFileSystemStorage = createExpoFileSystemStorage({
  storagePath: `${FileSystem.documentDirectory}customPersistStorageData/`,
  encoding: FileSystem.EncodingType.BASE64,
  debug: true,
  logger: {
    debug: customDebugFunction,
    error: customErrorFunction,
  },
  beforeInit: customBeforeInitFunction,
  afterInit: customAfterInitFunction,
});

// Configuration for Redux Persist
const persistConfig: PersistConfig<RootState> = {
  key: "root",
  // Use the ExpoFileSystemStorage as the storage engine
  storage: expoFileSystemStorage,
  // ... Add other persist config options if needed
};

const persistedReducer = persistReducer(persistConfig, rootReducer);

export const store = configureStore({
  reducer: persistedReducer,
  // ... Add other config options if needed
});

Options

The storage engine provides various options for customization. Fine-tune your storage engine with the following configuration options:

| Option | Type | Default Value | Description | | ------------- | ---------------------------------- | ------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | | storagePath | string | FileSystem.documentDirectory + 'persistStorageData/' | The directory path for storing persisted data. It is recommended to provide a custom path for better organization and to avoid potential conflicts with other files in the default | directory. | | encoding | FileSystem.EncodingType | FileSystem.EncodingType.UTF8 | The encoding type for reading and writing files. Use FileSystem.EncodingType.BASE64 for binary data or if your application deals with non-text data. | | debug | boolean | false | Enable/disable debug mode. When enabled, detailed logs will be printed during development, aiding in debugging and understanding the library's actions. | | logger | { debug: Logger, error: Logger } | { debug: console.log, error: console.error } | Custom logger object with debug and error methods. You can provide your own logger functions to tailor the logging behavior according to your application's needs. | | beforeInit | () => Promise<void> \| void | undefined | Callback function to be executed before initializing the storage. Use this for performing custom actions or setup before the storage engine is ready. | | afterInit | () => Promise<void> \| void | undefined | Callback function to be executed after initializing the storage. Use this for performing custom actions or setup after the storage engine is ready. |

API

This example demonstrates the direct usage of getItem and setItem methods from ExpoFileSystemStorage. For more details and available methods, please refer to the ExpoFileSystemStorage class.

import { createExpoFileSystemStorage } from "redux-persist-expo-file-system-storage";

// Create an instance of ExpoFileSystemStorage
const expoFileSystemStorage = createExpoFileSystemStorage();

// Example usage of getItem
async function exampleGetItem() {
  try {
    const key = "exampleKey";
    const value = await expoFileSystemStorage.getItem(key);
    console.log(`Item with key '${key}' has value:`, value);
  } catch (error) {
    console.error("Error getting item:", error);
  }
}

// Example usage of setItem
async function exampleSetItem() {
  try {
    const key = "exampleKey";
    const value = "exampleValue";
    await expoFileSystemStorage.setItem(key, value);
    console.log(`Item with key '${key}' set successfully!`);
  } catch (error) {
    console.error("Error setting item:", error);
  }
}

exampleGetItem();
exampleSetItem();

Contributing

Contributions are welcome! If you encounter issues or have suggestions, please feel free to open an issue or submit a pull request.

This package uses Changesets for version management. For further information on contributing and working with Changesets, refer to the Changesets Documentation: Using Changesets.

License

This project is licensed under the MIT License - see the LICENSE file for details.