ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

在 React Native 中集成 Jotai 与 MMKV:用 atomWithMMKV 实现原子状态持久化

在 React Native 中集成 Jotai 与 MMKV:用 atomWithMMKV 实现原子状态持久化 【免费下载链接】react-native-mmkv⚡️ The fastest key/value storage for React Native. ~30x faster than AsyncStorage!项目地址https://gitcode.com/gh_mirrors/re/react-native-mmkv点击查看免费下载导读Jotai 是 React 生态中基于原子atom的轻量级状态管理库而 react-native-mmkv 则提供了约 30 倍于 AsyncStorage 的同步键值存储能力。本文基于仓库中的 docs/WRAPPER_JOTAI.md 官方集成指南讲解如何通过 Jotai 官方提供的atomWithStoragecreateJSONStorage工具把 MMKV 无缝接入 Jotai 的原子状态体系从而让每一个 atom 的读写自动落盘、跨应用启动持久化。读完本文你将掌握完整的atomWithMMKV封装代码、其底层 API 调用链以及 JSON 序列化、跨进程变更监听等关键机制。为什么需要 atomWithMMKVJotai 本身的atom()只负责内存中的状态刷新应用后即丢失。要实现持久化Jotai 官方在jotai/utils中提供了atomWithStorage(key, initialValue, storage)——它要求传入一个符合AsyncStorage 风格接口的storage对象该对象必须实现四个方法方法签名职责getItem(key: string) string \| null读取指定 key 的字符串值setItem(key: string, value: string) void写入字符串值removeItem(key: string) void删除指定 keysubscribe(key: string, callback) () void订阅某 key 的变更返回取消订阅函数而 MMKV 原生暴露的正是同步的getString/set/remove以及addOnValueChangedListener监听能力二者接口天然契合。因此只需要写一个薄薄的适配层就能让 Jotai 用上 MMKV 的高性能同步存储而无需引入任何第三方桥接库。第一步安装依赖在使用本封装前先确保安装 react-native-mmkvV4 版本基于 Nitro Modules及其运行时依赖npm install react-native-mmkv react-native-nitro-modules cd ios pod install如果你的项目使用 Exponpx expo install react-native-mmkv react-native-nitro-modules npx expo prebuild同时安装 Jotainpm install jotai安装完成后即可创建全局唯一的 MMKV 实例并开始编写适配层。核心封装atomWithMMKV仓库官方指南给出了完整的atomWithMMKV实现它位于全局存储实例之上通过createJSONStorage把 Jotai 与 MMKV 绑定起来import { atomWithStorage, createJSONStorage } from jotai/utils; import { createMMKV } from react-native-mmkv; const storage createMMKV(); function getItem(key: string): string | null { const value storage.getString(key) return value ? value : null } function setItem(key: string, value: string): void { storage.set(key, value) } function removeItem(key: string): void { storage.remove(key); } function subscribe( key: string, callback: (value: string | null) void ): () void { const listener (changedKey: string) { if (changedKey key) { callback(getItem(key)) } } const { remove } storage.addOnValueChangedListener(listener) return () { remove() } } export const atomWithMMKV T(key: string, initialValue: T) atomWithStorageT( key, initialValue, createJSONStorageT(() ({ getItem, setItem, removeItem, subscribe, })), { getOnInit: true } );这段代码拆解来看每一层都对应 MMKV 原生 API 的同步能力1. 单例存储实例const storage createMMKV()创建了默认 IDmmkv.default的存储实例。查看源码 createMMKV.ts 可以看到在非测试环境下它会调用原生工厂创建 C HybridObject并自动挂载内存警告监听addMemoryWarningListener与应用激活时的内容变更检查addContentChangedListener。官方建议整个应用复用同一个导出实例而不是每次创建// storage.ts import { createMMKV } from react-native-mmkv export const storage createMMKV()如果希望存储按用户隔离或加密也可以传入配置例如export const storage createMMKV({ id: user-${userId}-storage, encryptionKey: hunter2, encryptionType: AES-256, mode: multi-process, })配置项的含义可参见 MMKVFactory.nitro.ts 中的Configuration类型定义id实例 ID默认mmkv.default多实例需使用不同 IDpath存储根路径默认位于$(Documents)/mmkv/iOS 上若配置了 App Group 会自动使用共享目录encryptionKey/encryptionType加密密钥与算法AES-128默认 /AES-256密钥长度分别要求 16 字节 / 32 字节modesingle-process默认或multi-processApp Clip、扩展等跨进程场景readOnly只读模式set会抛错compareBeforeSet写入前先比较值是否相等相等则跳过落盘。2. getItem读取字符串storage.getString(key)是 MMKV 提供的同步读取方法接口定义见 MMKV.nitro.ts。当 key 不存在时它返回undefined因此这里通过value ? value : null归一化为 AsyncStorage 风格的null返回值保证 Jotai 能正确区分「有值」与「无值」。3. setItem写入字符串storage.set(key, value)是同步写入方法可接受boolean | string | number | ArrayBuffer四类值。注意 Jotai 的 storage 接口约定的是字符串真正的类型序列化由createJSONStorage负责见下文。4. removeItem删除键值storage.remove(key)删除指定 key返回布尔值表示是否删除成功。这正好满足 AsyncStorage 风格接口的删除语义。5. subscribe跨实例变更订阅Jotai 要求 storage 提供订阅能力以便多个页面、多个 tab 甚至多个进程间的状态保持同步。封装中利用了 MMKV 的addOnValueChangedListener(listener)该监听器会在任意key 被set或删除时回调 key 名称注意删除也会触发回调见 createMockMMKV.ts 中remove对notifyListeners的调用。因此适配层需要先过滤出自己关心的 key再通过getItem(key)拉取最新值回传给 Jotai最后返回remove()作为取消订阅函数。这套「事件驱动 主动拉取」的订阅模式与 LISTENERS.md 中描述的值变更监听机制一脉相承——即使存储被 App 扩展、App Clip 或后台服务修改应用回到前台时也会通过checkContentChanged()检测外部变更并触发监听器保证 atom 状态不被陈旧数据覆盖。6. getOnInit启动即同步atomWithStorage的第四个参数{ getOnInit: true }表示 atom 初始化时就从存储中读取持久化值而不是等到订阅回调触发这保证了应用启动后界面能立即呈现上次会话保存的状态。使用方式封装完成后创建持久化 atom 与普通atom()用法几乎一致只需把atomWithMMKV(key, initialValue)当作atom()的替代品即可const myAtom atomWithMMKV(my-atom-key, value);在组件中使用import { useAtom } from jotai; const myAtom atomWithMMKV(settings.theme, light); function SettingsScreen() { const [theme, setTheme] useAtom(myAtom); // setTheme(dark) 会同步写入 MMKV并在下次启动时恢复 }因为 atom 以字符串 key 为维度与 MMKV 键一一对应你可以为不同业务域创建多个持久化 atom例如用户信息、主题偏好、购物车数据等底层存储实例只有一个但原子状态各自独立落盘。JSON 序列化createJSONStorage 做了什么封装中所有 getItem/setItem 都以字符串为输入输出那么对象类型如{ name: string, age: number }如何持久化答案是createJSONStorage正如原文档注释所强调的它会自动对值执行JSON.stringify()/JSON.parse()。const userAtom atomWithMMKVUser(user.profile, { name: Marc, age: 21, }); // 写入时storage.set(user.profile, {name:Marc,age:21}) // 读取时storage.getString(user.profile) 后再 JSON.parse这意味着你可以直接持久化对象、数组、字符串、数字、布尔值等任意可 JSON 序列化的类型MMKV 底层始终存的是 UTF-8 字符串与原生端getString/set的数据形态完全一致与 README.md 中「用JSON.stringify存对象」的官方建议互为印证若值在运行时被外部进程直接以非 JSON 格式写入JSON.parse可能抛错——这是所有 JSON 存储方案的固有约束建议保持 atom 写入路径的一致性。底层实现与测试环境行为从源码结构看这套适配层在三种环境下有对应的行为原生iOS / AndroidcreateMMKV()通过 Nitro Modules 创建 C 实现的同步存储createMMKV.ts读写与监听均为同步调用这也是其性能优势的来源Web 端createMMKV的 Web 实现createMMKV.web.ts基于localStorage同样实现了getString/set/remove/addOnValueChangedListener与getAllKeys等完整接口因此atomWithMMKV无需改动即可在 Web 上运行需注意 Web 端不支持encryptionKey与path会直接抛错且浏览器禁用 localStorage 时数据不会持久化测试环境Jest / VitestcreateMMKV()会自动返回基于内存 Map 的 mock 实例createMockMMKV.tsset/remove同样会触发监听器回调所以上述subscribe逻辑在单元测试中可以完整验证不需要 mock Jotai 或 MMKV 原生模块。注意事项与最佳实践key 命名约定atom 的 key 同时是 MMKV 的存储键建议使用带命名空间的字符串如settings.theme、user.profile避免不同模块间 key 冲突初始值语义atomWithStorage的initialValue只在存储中不存在该 key 时生效一旦写入过下次启动以存储值优先getOnInit: true保证这一点不要手动改动存储通过storage.set(...)直接写入同名 key 也会触发订阅回调并同步到对应 atom但反过来 atom 变更会覆盖手动写入的值应避免两套写入路径同时操作同一 key跨进程共享若 atom 数据需要被 App Clip / 扩展读取应在createMMKV()时配置mode: multi-process并确保 iOS 端设置了 App Group 目录敏感数据加密对登录态、token 等敏感 atom可在创建存储实例时配置encryptionKeyMMKV 会以 AES-128默认或 AES-256 加密落盘文件。小结通过atomWithMMKVJotai 的状态管理获得了 MMKV 同步读写的性能底座atom 读写零异步开销、数据跨启动持久化、跨进程变更自动同步且无需任何第三方胶水库。整个封装仅需约 40 行代码核心思路AsyncStorage 风格接口适配也适用于 redux-persist、recoil、zustand persist 等其他状态库的 MMKV 集成是 react-native-mmkv 官方推荐的整合范式之一。更完整的 API 说明可继续阅读 HOOKS.md 与 LISTENERS.md。赞分享【免费下载链接】react-native-mmkv⚡️ The fastest key/value storage for React Native. ~30x faster than AsyncStorage!项目地址https://gitcode.com/gh_mirrors/re/react-native-mmkv点击查看免费下载相关推荐React Native MMKV与Recoil集成原子状态持久化的高效实现React Native MMKV与Recoil集成原子状态持久化的高效实现 React Native MMKV作为最快的键值存储解决方案与Recoil状态PhxQueue与Kafka/RabbitMQ对比分析为何选择微信开源的分布式队列PhxQueue与Kafka/RabbitMQ对比分析为何选择微信开源的分布式队列 在当今分布式系统架构中 分布式消息队列 已成为微服务架构的核心组件。面对react-native-mmkv 与 Recoil 集成用 atomEffect 实现 atom 状态持久化react native mmkv 与 Recoil 集成用 atomEffect 实现 atom 状态持久化 Recoil 的 atom 状态默认只存在于内上一篇DistroAV 启动报错 NDI 加载失败怎么办一份 NDI Runtime 缺失修复实战指南下一篇D2DX暗黑破坏神2高清补丁入门到进阶一次配置找回宽屏、高帧率与清晰画面创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表