| V4 文档 | 旧版 V3 文档 |
|---|
MMKV
React Native 最快的键值存储。
- MMKV 是由微信开发的高效、轻量级移动端键值存储框架。更多信息请参阅 Tencent/MMKV
- react-native-mmkv 是一个库,允许你通过快速且直接的 JS 绑定到原生 C++ 库,在 React Native 应用中轻松使用 MMKV。
特性
- 获取 和 设置 字符串、布尔值、数字和 ArrayBuffer
- 完全同步 调用,无需 async/await,无需 Promise,无需 Bridge。
- 支持加密(安全存储)
- 支持多实例(将用户数据与全局数据分离)
- 可自定义存储位置
- 高性能,因为所有代码均用 C++ 编写
- 比 AsyncStorage 快约 30 倍
- 使用 JSI 和 C++ NitroModules 替代“旧版” Bridge
- 支持 iOS、Android 和 Web
- 易于使用的 React Hooks API
[!IMPORTANT]
- 你正在查看 MMKV V4。如果你仍在使用 V3,请查看此处 V3 文档!
- react-native-mmkv V4 现在是一个 Nitro Module。更多信息请参阅 V4 升级指南。
基准测试
StorageBenchmark 通过从存储中读取值 1000 次来比较流行的存储库:
安装
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。例如,您可以将全局应用的存储和已登录用户的存储分开。(如果指定了path或encryptionKey字段,则此项为必填项,否则默认为:'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 原生日志的详尽程度。
| 值 | 级别 |
|---|---|
| 0 | Debug |
| 1 | Info |
| 2 | Warning |
| 3 | Error |
| 4 | None |
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。
文档
- Hooks
- 值变更监听器
- 从 AsyncStorage 迁移
- 使用 MMKV 与 redux-persist
- 使用 MMKV 与 recoil
- 使用 MMKV 与 mobx-persist-storage
- 使用 MMKV 与 mobx-persist
- 使用 MMKV 与 zustand persist-middleware
- 使用 MMKV 与 jotai
- 使用 MMKV 与 react-query
- 使用 MMKV 与 Tinybase
- 该库与 react-native-mmkv-storage 有何不同?
LocalStorage 和内存存储(Web)
如果用户选择在浏览器中禁用 LocalStorage,该库将自动提供一个有限的内存存储作为替代方案。然而,这种内存存储不会持久化数据,如果用户刷新页面或关闭浏览器,可能会经历数据丢失。为了优化用户体验,请考虑在您的应用中实现一个合适的解决方案来处理此场景。
局限性
- react-native-mmkv V4 需要 react-native 0.76 或更高版本。
- 由于 react-native-mmkv 使用 JSI 进行同步的原生方法调用,因此不再可能进行远程调试(例如使用 Chrome)。相反,您应该使用 Flipper 或 React 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