ITADN
mrousavy/react-native-mmkv
README.md
以下内容由 AI 翻译,如有问题请点此提交 issue 反馈
V4 文档旧版 V3 文档
react-native-mmkv

MMKV

React Native 最快的键值存储。


  • MMKV 是由微信开发的高效、轻量级移动端键值存储框架。更多信息请参阅 Tencent/MMKV
  • react-native-mmkv 是一个库,允许你通过快速且直接的 JS 绑定到原生 C++ 库,在 React Native 应用中轻松使用 MMKV

特性

  • 获取设置 字符串、布尔值、数字和 ArrayBuffer
  • 完全同步 调用,无需 async/await,无需 Promise,无需 Bridge。
  • 支持加密(安全存储)
  • 支持多实例(将用户数据与全局数据分离)
  • 可自定义存储位置
  • 高性能,因为所有代码均用 C++ 编写
  • 比 AsyncStorage 快约 30 倍
  • 使用 JSIC++ NitroModules 替代“旧版” Bridge
  • 支持 iOSAndroidWeb
  • 易于使用的 React Hooks API

[!IMPORTANT]

基准测试

StorageBenchmark 通过从存储中读取值 1000 次来比较流行的存储库:

MMKV 与其他存储库:从存储中读取值 1000 次。
在 iPhone 11 Pro 上以毫秒为单位测量,数值越低越好。

安装

React Native

npm install react-native-mmkv react-native-nitro-modules
cd ios && pod install

Expo

npx expo install react-native-mmkv react-native-nitro-modules
npx expo prebuild

用法

创建新实例

要创建 MMKV 存储的新实例,请使用 MMKV 构造函数。建议在整个应用中复用此实例,而不是每次创建新实例,因此 export storage 对象。

默认

import { createMMKV } from 'react-native-mmkv'

export const storage = createMMKV()

这将使用默认的 MMKV 存储 ID(mmkv.default)创建一个新的存储实例。

App Groups or Extensions

如果你希望在同一组内的应用和其他应用或应用扩展之间共享 MMKV 数据,请打开 Info.plist 并创建一个具有你应用组值的 AppGroupIdentifier 键。MMKV 随后会自动将数据存储在该应用组内,其他同一组内的应用或应用扩展可以利用 MMKV 的多进程模式对其进行读写。 参见 Configuring App Groups.

Customize

import { createMMKV } from 'react-native-mmkv'

export const storage = createMMKV({
  id: `user-${userId}-storage`,
  path: `${USER_DIRECTORY}/storage`,
  encryptionKey: 'hunter2',
  encryptionType: 'AES-256',
  mode: 'multi-process',
  readOnly: false,
  compareBeforeSet: false,
})

这将使用自定义的 MMKV 存储 ID 创建一个新的存储实例。通过使用自定义存储 ID,您的存储将与应用的默认 MMKV 存储隔离。

以下值可以配置:

  • id: MMKV 实例的 ID。如果您想使用多个实例,请使用不同的 ID。例如,您可以将全局应用的存储和已登录用户的存储分开。(如果指定了 pathencryptionKey 字段,则此项为必填项,否则默认为:'mmkv.default'
  • path: MMKV 实例的根路径。默认情况下,MMKV 将文件存储在 $(Documents)/mmkv/ 内。您可以在 MMKV 初始化时自定义 MMKV 的根目录(文档:iOS / Android
  • encryptionKey: MMKV 实例的加密/解密密钥。默认情况下,MMKV 以明文形式将所有键值存储在文件中,依赖 iOS/Android 的沙盒机制来确保文件加密。如果您担心信息泄露,可以选择对 MMKV 进行加密。(文档:iOS / Android
  • encryptionType: MMKV 实例的加密/解密算法。默认情况下,将使用 AES-128 加密,但您可以切换到 AES-256 以获得更高的安全性。
  • mode: MMKV 的进程行为 - 当设置为 multi-process 时,MMKV 实例将假设数据可能从外部被修改(例如 App Clips、扩展或 App Groups)。
  • readOnly: 此 MMKV 实例是否应处于只读模式。如果不需要,这通常更高效,并避免对数据进行不必要的写入。任何对 set(..) 的调用都将抛出异常。
  • compareBeforeSet: 此 MMKV 实例在将值写入磁盘之前是否会比较值的相等性。默认情况下此功能已禁用,如果值被重复写入磁盘(即使它们已经持久化),启用它可能会提高性能。

集合

storage.set('user.name', 'Marc')
storage.set('user.age', 21)
storage.set('is-mmkv-fast-asf', true)

获取

const username = storage.getString('user.name') // 'Marc'
const age = storage.getNumber('user.age') // 21
const isMmkvFastAsf = storage.getBoolean('is-mmkv-fast-asf') // true

钩子

const [username, setUsername] = useMMKVString('user.name')
const [age, setAge] = useMMKVNumber('user.age')
const [isMmkvFastAsf, setIsMmkvFastAsf] = useMMKVBoolean('is-mmkv-fast-asf')

按键

// checking if a specific key exists
const hasUsername = storage.contains('user.name')

// getting all keys
const keys = storage.getAllKeys() // ['user.name', 'user.age', 'is-mmkv-fast-asf']

// delete a specific key + value
const wasRemoved = storage.remove('user.name')

// delete all keys
storage.clearAll()

对象

const user = {
  username: 'Marc',
  age: 21
}

// Serialize the object into a JSON string
storage.set('user', JSON.stringify(user))

// Deserialize the JSON string into an object
const jsonUser = storage.getString('user') // '{ "username": "Marc", "age": 21 }'
const userObject = JSON.parse(jsonUser) // { username: 'Marc', age: 21 }

加密

// encrypt all data with a private key using AES-128
storage.encrypt('hunter2')
// encrypt all data with a private key using AES-256
storage.encrypt('hunter2again', 'AES-256')

// remove encryption
storage.decrypt()

缓冲区

const buffer = new ArrayBuffer(3)
const dataWriter = new Uint8Array(buffer)
dataWriter[0] = 1
dataWriter[1] = 100
dataWriter[2] = 255
storage.set('someToken', buffer)

const buffer = storage.getBuffer('someToken')
console.log(buffer) // [1, 100, 255]

大小

// get size of MMKV storage in bytes
const size = storage.byteSize
if (size >= 4096) {
  // clean unused keys and clear memory cache
  storage.trim()
}

从另一个 MMKV 实例导入所有数据

要从另一个 MMKV 实例导入所有键和值,请使用 importAllFrom(...)

const storage = createMMKV(...)
const otherStorage = createMMKV(...)

const importedCount = storage.importAllFrom(otherStorage)

检查 MMKV 实例是否存在

要检查 MMKV 实例是否存在,请使用 existsMMKV(...)

import { existsMMKV } from 'react-native-mmkv'

const exists = existsMMKV('my-instance')

删除 MMKV 实例

要删除一个 MMKV 实例,请使用 deleteMMKV(...)

import { deleteMMKV } from 'react-native-mmkv'

const wasDeleted = deleteMMKV('my-instance')

日志级别

默认情况下,MMKV 在调试构建中使用 Debug 级别,在发布构建中使用 Warning 级别。您可以在构建时覆盖此设置,以控制 MMKV 原生日志的详尽程度。

级别
0Debug
1Info
2Warning
3Error
4None

Android

在您的应用的 android/gradle.properties 中设置 MMKV_logLevel

MMKV_logLevel=4

iOS

在您的应用的 ios/Podfile 中设置 $MMKVLogLevel,然后运行 pod install

$MMKVLogLevel = 4

或者在 pod install 期间使用环境变量:

MMKV_LOG_LEVEL=4 pod install

使用 Jest 或 Vitest 进行测试

在使用 Jest 或 Vitest 进行测试时,会自动使用一个模拟的 MMKV 实例,因此您可以在测试中像平常一样使用 createMMKV()。有关使用 Jest 的示例,请参阅 example/__tests__/MMKV.harness.ts

文档

LocalStorage 和内存存储(Web)

如果用户选择在浏览器中禁用 LocalStorage,该库将自动提供一个有限的内存存储作为替代方案。然而,这种内存存储不会持久化数据,如果用户刷新页面或关闭浏览器,可能会经历数据丢失。为了优化用户体验,请考虑在您的应用中实现一个合适的解决方案来处理此场景。

局限性

  • react-native-mmkv V4 需要 react-native 0.76 或更高版本。
  • 由于 react-native-mmkv 使用 JSI 进行同步的原生方法调用,因此不再可能进行远程调试(例如使用 Chrome)。相反,您应该使用 FlipperReact DevTools

集成

Rozenite

使用 @rozenite/mmkv-plugin 通过 Rozenite 调试你的 MMKV 存储。

Reactotron

使用 reactotron-react-native-mmkv 通过 Reactotron 自动记录对 MMKV 存储的写入操作。请参阅文档了解如何配置此插件与 Reactotron。

社区 Discord

加入 Margelo 社区 Discord 以讨论 react-native-mmkv 或其他 Margelo 库。

大规模采用

react-native-mmkv 以 现状 提供,我在业余时间对其进行开发。

如果你正在生产应用中集成 react-native-mmkv,请考虑 资助此项目联系我 以获取高级企业支持、问题协助、优先修复错误、请求功能、协助集成 react-native-mmkv 等。

贡献

请参阅 贡献指南 以了解如何为仓库做出贡献以及开发工作流程。

许可证

MIT