React Native MMKV完整封装

目录

一、架构

二、核心封装

三、数据隔离加密封装


一、架构

├─mmkv

│ │ index.ts

│ │

│ ├─adapters

│ │ BaseManager.ts

│ │ BaseStorage.ts

│ │ index.ts

│ │ LocalStorage.ts

│ │ storageFactory.ts

│ │ StorageManager.ts

│ │

│ ├─constants

│ │ index.ts

│ │ user.ts

│ │

│ ├─instances

│ │ appStorage.ts

│ │ cacheStorage.ts

│ │ userStorage.ts

│ │

│ └─utils

│ keyGenerator.ts

核心封装 LocalStorage.ts,用户数据隔离加密封装管理StorageManager.ts。

二、核心封装

BaseStorage.ts

javascript 复制代码
/**
 * @author Dragon Wu
 * @created 2026/01/25 20:46
 * @description MMKV封装对象的基类型
 */

interface BaseStorage {
  set<T = unknown>(key: string, value: T): void;
  get<T = unknown>(key: string): T | null;
  remove(key: string): void;
  clear(): void;
  setString(key: string, value: string): void;
  getString(key: string): string | null;
  setNumber(key: string, value: number): void;
  getNumber(key: string): number | null;
  setBoolean(key: string, value: boolean): void;
  getBoolean(key: string): boolean | null;
  setObject<T extends object>(key: string, value: T): void;
  getObject<T extends object>(key: string): T | null;
  setBuffer(key: string, value: ArrayBuffer): void;
  getBuffer(key: string): ArrayBuffer | null;
  has(key: string): boolean;
  keys(): string[];
  getMulti<T = unknown>(keys: string[]): Record<string, T | null>;
  setMulti(items: Array<{ key: string; value: unknown }>): void;
  addListener(callback: (key: string) => void): { clearListener: () => void };
}

export default BaseStorage;

LocalStorage.ts

javascript 复制代码
/**
 * @author Dragon Wu
 * @created 2026/01/26 20:49
 * @description 本地数据管理 适用于范围隔离的数据,如:用户数据,数据都是加密存储的
 */

import { isBlank } from '@/utils/string';
import LocalStorage from './LocalStorage';
import { createSecureStorage } from './storageFactory';
import BaseManager from './BaseManager';

export default class StorageManager implements BaseManager {
  private currentId: string | null = null;
  private storages = new Map<string, LocalStorage>();
  private secret: string | undefined; // 加密密钥种子

  constructor(secret?: string) {
    this.secret = secret;
  }

  getCurrentStorage(): LocalStorage | null {
    return this.currentId ? (this.storages.get(this.currentId) ?? null) : null;
  }

  getCurrentId(): string | null {
    return this.currentId;
  }

  switchStorage(storageId: string): LocalStorage {
    if (isBlank(storageId)) {
      throw Error('switchStorage: storageId is required');
    }

    let storage = this.storages.get(storageId);

    if (!storage) {
      storage = createSecureStorage(storageId, this.secret);
      this.storages.set(storageId, storage);
    }

    this.currentId = storageId;
    return storage;
  }

  clearStorage(storageId: string): void {
    const storage = this.storages.get(storageId);
    if (storage) {
      storage.clear();
      this.storages.delete(storageId);
    }

    if (this.currentId === storageId) {
      this.currentId = null;
    }
  }

  getAllStorageIds(): string[] {
    return Array.from(this.storages.keys());
  }

  cleanup(): void {
    this.storages.clear();
    this.currentId = null;
  }
}

使用方法:

cacheStorage.ts

javascript 复制代码
/**
 * @author Dragon Wu
 * @created 2026/01/25 20:46
 * @description 缓存实例
 */

import { createStorage } from '@/stores/mmkv/adapters';
import { STORAGE_KEYS } from '@/stores/mmkv/constants';

export const cacheStorage = createStorage(STORAGE_KEYS.CACHE);

三、数据隔离加密封装

一般用于应用级加密存储用户数据。

keyGenerator.ts

javascript 复制代码
/**
 * @author Dragon Wu
 * @created 2026/01/25 22:08
 * @description 动态加密key生成器 场景:MMVK加密key
 */

export const generateKey = (id: string): string => {
  const cleanId = id.trim();
  if (!cleanId) throw new Error('generateKey: id不能为空');

  const APP_SALT = 'scoped_storage_fixed_salt_2026_v1_secure';
  const seed = `v1:${cleanId}:${APP_SALT}`;

  // 改良的DJB2算法(完全无位运算)
  let hash = 5381;

  for (let i = 0; i < seed.length; i++) {
    // 标准DJB2: hash = hash * 33 + charCode
    // 33 = 32 + 1 = (hash << 5) + hash
    hash = hash * 32 + hash + seed.charCodeAt(i);

    // 保持在32位范围内
    if (hash > 0xffffffff) {
      hash = hash % 0xffffffff;
    }
  }

  // 使用36进制增加熵值
  const base36 = Math.abs(hash).toString(36);
  const keyBase = `sk_${base36}_${cleanId.substring(0, 4)}`;

  // 固定32字符
  return keyBase.padEnd(32, '_').substring(0, 32);
};

storageFactory.ts

javascript 复制代码
/**
 * @author Dragon Wu
 * @created 2026/01/26 20:49
 * @description 数据生产工厂
 */

import { Configuration } from 'react-native-mmkv';
import LocalStorage from './LocalStorage';
import { generateKey } from '@/stores/mmkv/utils/keyGenerator';

/**
 * 创建加密存储(用于敏感数据,特别敏感的数据不要使用MMKV,需使用Keychain)
 * @param storageId - 存储的唯一标识
 * @param secret - 加密密钥种子
 * @param config - 额外配置
 */
export const createSecureStorage = (storageId: string, secret?: string, config?: Configuration) => {
  return new LocalStorage({
    ...(config ?? {}),
    id: storageId,
    encryptionKey: generateKey(secret ? `${secret}:${storageId}` : storageId)
  });
};

/**
 * 创建普通存储(用于非敏感数据)
 * @param storageId - 存储的唯一标识
 * @param config - 额外配置
 */
export const createStorage = (storageId: string, config?: Configuration) => {
  return new LocalStorage({
    ...(config ?? {}),
    id: storageId
  });
};

BaseManager.ts

javascript 复制代码
/**
 * @author Dragon Wu
 * @created 2026/01/26 20:46
 * @description StorageManager的实现接口
 */

import LocalStorage from './LocalStorage';

interface BaseManager {
  getCurrentStorage(): LocalStorage | null;
  getCurrentId(): string | null;
  switchStorage(storageId: string): LocalStorage;
  clearStorage(storageId: string): void;
  getAllStorageIds(): string[];
  cleanup(): void;
}

export default BaseManager;

StorageManager.ts

javascript 复制代码
/**
 * @author Dragon Wu
 * @created 2026/01/26 20:49
 * @description 本地数据管理 适用于范围隔离的数据,如:用户数据,数据都是加密存储的
 */

import { isBlank } from '@/utils/string';
import LocalStorage from './LocalStorage';
import { createSecureStorage } from './storageFactory';
import BaseManager from './BaseManager';

export default class StorageManager implements BaseManager {
  private currentId: string | null = null;
  private storages = new Map<string, LocalStorage>();
  private secret: string | undefined; // 加密密钥种子

  constructor(secret?: string) {
    this.secret = secret;
  }

  getCurrentStorage(): LocalStorage | null {
    return this.currentId ? (this.storages.get(this.currentId) ?? null) : null;
  }

  getCurrentId(): string | null {
    return this.currentId;
  }

  switchStorage(storageId: string): LocalStorage {
    if (isBlank(storageId)) {
      throw Error('switchStorage: storageId is required');
    }

    let storage = this.storages.get(storageId);

    if (!storage) {
      storage = createSecureStorage(storageId, this.secret);
      this.storages.set(storageId, storage);
    }

    this.currentId = storageId;
    return storage;
  }

  clearStorage(storageId: string): void {
    const storage = this.storages.get(storageId);
    if (storage) {
      storage.clear();
      this.storages.delete(storageId);
    }

    if (this.currentId === storageId) {
      this.currentId = null;
    }
  }

  getAllStorageIds(): string[] {
    return Array.from(this.storages.keys());
  }

  cleanup(): void {
    this.storages.clear();
    this.currentId = null;
  }
}

使用案例:

userStorage.ts

javascript 复制代码
/**
 * @author Dragon Wu
 * @created 2026/01/27
 * @description 用户存储管理器
 */

import { StorageManager } from '@/stores/mmkv/adapters';
import { STORAGE_KEYS } from '@/stores/mmkv/constants';

const userManager = new StorageManager(STORAGE_KEYS.USER);

export default userManager;

总结到此!

相关推荐
崔庆才丨静觅2 分钟前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60611 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了1 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅1 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅1 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅2 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment2 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅2 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊2 小时前
jwt介绍
前端
爱敲代码的小鱼2 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax