Skip to Content
API ReferenceStorage Utilities

Storage Utilities

RNCopilot provides a typed wrapper around react-native-mmkv for persistent key-value storage. The wrapper adds a result-object pattern for error handling, a listener system for reactivity, and React hooks for component integration.

Source: src/utils/storage/

STORAGE_KEYS

All storage keys are defined as a typed constant object. Using these constants instead of raw strings prevents typos and enables IDE autocompletion.

import { STORAGE_KEYS } from '@/utils/storage'; // Available keys: STORAGE_KEYS.preferences.theme // 'user_theme_preference' STORAGE_KEYS.preferences.themePreset // 'user_theme_preset' STORAGE_KEYS.preferences.language // 'user_language' STORAGE_KEYS.preferences.onboardingCompleted // 'onboarding_completed' STORAGE_KEYS.preferences.notificationsEnabled // 'notifications_enabled' STORAGE_KEYS.auth.lastEmail // 'auth_last_email' STORAGE_KEYS.app.lastVersion // 'app_last_version' STORAGE_KEYS.app.launchCount // 'app_launch_count'

The StorageKey type is derived from this object, so TypeScript enforces that only valid keys are used.

Result Object Pattern

All imperative storage functions return a StorageResult<T> object. Always check .success before using .data:

interface StorageResult<T> { success: boolean; data?: T; error?: Error; }
import { getItem, STORAGE_KEYS } from '@/utils/storage'; const result = getItem<string>(STORAGE_KEYS.preferences.language); if (result.success && result.data) { console.log('Language:', result.data); } else if (!result.success) { console.error('Storage error:', result.error?.message); }

Never access .data without first checking .success. On failure, .data is undefined and .error contains the Error object.

Imperative Functions

These functions can be called anywhere — in components, hooks, services, or utility code.

getItem

function getItem<T extends StorageValue>(key: StorageKey): StorageResult<T | null>

Retrieves a value by key. Returns { success: true, data: null } if the key does not exist. Automatically parses JSON strings back into objects.

setItem

function setItem<T extends StorageValue>(key: StorageKey, value: T): StorageResult<T>

Stores a value. Supports string, number, boolean, and object (serialized as JSON). Passing null or undefined removes the key.

removeItem

function removeItem(key: StorageKey): StorageResult<void>

Removes a key from storage.

hasItem

function hasItem(key: StorageKey): boolean

Returns true if the key exists in storage.

clear

function clear(): StorageResult<void>

Removes all keys from storage.

getAllKeys

function getAllKeys(): StorageResult<StorageKey[]>

Returns all stored keys.

getStorageSize

function getStorageSize(): number

Returns an approximate size in bytes of all stored data.

addListener

function addListener<T extends StorageValue>( key: StorageKey, callback: (value: T | null) => void ): () => void

Subscribes to changes for a specific key. Returns an unsubscribe function.

initializeStorage

function initializeStorage(options?: { id?: string; encryptionKey?: string; }): void

Initializes the MMKV instance. Called automatically on first access with default options. Call explicitly if you need a custom ID or encryption.

React Hooks

useStorage

A reactive hook that reads, writes, and subscribes to a storage key. Re-renders the component when the value changes.

function useStorage<T extends StorageValue>( key: StorageKey, options?: UseStorageOptions<T> ): UseStorageReturn<T>

Options:

OptionTypeDefaultDescription
defaultValueTundefinedValue to use if key does not exist
initializeWithDefaultbooleanfalseWrite defaultValue to storage if key is missing

Returns:

PropertyTypeDescription
valueT | nullCurrent value
setValue(value: T | null) => voidUpdate the stored value
removeValue() => voidRemove the key from storage
loadingbooleantrue during initial read
errorError | nullError if the last operation failed
refresh() => voidRe-read the value from storage

Example:

import { useStorage, STORAGE_KEYS } from '@/utils/storage'; export function LanguagePicker() { const { value: language, setValue: setLanguage, loading } = useStorage<string>(STORAGE_KEYS.preferences.language, { defaultValue: 'en', }); if (loading) return <Loading />; return ( <SegmentedControl value={language} onChange={setLanguage} options={['en', 'ar']} /> ); }

useStorageBoolean

A specialized version of useStorage for boolean values, with an added toggle convenience method.

function useStorageBoolean( key: StorageKey, options?: UseStorageOptions<boolean> ): UseStorageReturn<boolean> & { toggle: () => void }

Example:

import { useStorageBoolean, STORAGE_KEYS } from '@/utils/storage'; export function NotificationToggle() { const { value: enabled, toggle } = useStorageBoolean( STORAGE_KEYS.preferences.notificationsEnabled, { defaultValue: true } ); return ( <Switch value={enabled ?? true} onValueChange={toggle} /> ); }

Supported Value Types

The StorageValue type defines what can be stored:

type StorageValue = string | number | boolean | object | null;

Objects are automatically serialized to JSON on write and parsed on read.

Last updated on