RNOH 三方库全新发布:72 款库集体「修内功」,鸿蒙 RN 生态进入质量时代
RNOH 生态一次把 72 款三方库发到 npm,覆盖 React Native 0.72 到 0.84 四条框架线,却没加一个新功能——清 Issue、压崩溃、补测试、对齐行为、修文档。为什么「不发新功能」反而是成熟的信号。

原文公告:
CPF-RN 组织讨论 #19 · React Native OpenHarmony(RNOH)三方库版本发布公告[1] >
发布方:OpenHarmony React Native 三方库 SIG 团队
发布时间:2026 年 10 月
发布规模:72 款三方库,已全部发布至 npm
覆盖框架线:React Native 0.72 / 0.77 / 0.82 / 0.84
一句话总结:这个月不堆新功能,只做五件事——清 Issue、压崩溃、补测试、对齐行为、修文档。
一、「不发新功能」的消息,为什么反而是好消息
判断一个跨平台框架的三方库生态成熟到什么程度,看三件事:
第一段:有没有 —— 我的项目要用 WebView,鸿蒙上有没有?
第二段:全不全 —— 图片、音视频、地图、推送、加密……每个坑都有库填吗?
第三段:稳不稳 —— 库有了,但它在边界条件下会不会崩?行为跟安卓 iOS 一致吗?文档可信吗?
RNOH 生态已经走完了前两段。截至本月,CPF-RN 组织下 rntpc_* 系列加上合作仓库,覆盖了 UI 组件、图像处理、音视频、文件存储、网络通信、定位地图、设备能力、安全加密、推送、社交分享、动画等几乎所有常见场景——本文第三节完整列出了本次发布的 72 款。
于是第三段成为真正的门槛。生态的成熟标志不是库的数量,而是「敢不敢在正式项目里用」。而「敢不敢」取决于三件事:遇到问题有人修(Issue 清理)、跑起来不崩(稳定性)、换平台不改代码(行为一致性)。
这正是本月版本的核心——一次针对 72 款库的质量专项提升。
二、五个质量方向,逐个拆开看技术含量
公告给出的五个方向,看起来像套话,但每一条落到 RNOH 这个技术栈上都有具体含义。这条链路是 JS/TS 业务代码 → RNOH 桥接层(C++/ArkTS)→ 鸿蒙 ArkUI 原生能力,三层之间任何一层的语义偏差,最终都会以「iOS 上好好的,鸿蒙上不对」的形式暴露给业务方。
| 方向 | 公告表述 | 在 RNOH 栈里的实际含义 | 修复后你能感知到什么 |
|---|---|---|---|
| Issue 清理 | 逐一排查修复开发者与合作伙伴反馈的问题,清理积压缺陷 | 把社区/企业反馈从「待复现」推进到「已定位 → 已修 → 已验证」 | 之前踩到但被标记为 known issue 的坑,可能已经不需要 workaround 了 |
| 稳定性增强 | 排查边界条件与异常路径下的崩溃、内存泄漏 | 空值/空数组入参、重复调用、时序竞争、页面销毁后回调、大对象未释放——这些是原生实现最容易漏的分支 | 长时运行、反复进出页面、异常参数场景下的崩溃和 PSS 增长减少 |
| 测试用例覆盖 | 扩大自动化测试覆盖,补充功能与异常场景 | 三方库的鸿蒙实现要能像上游库一样被回归测试托住 | 后续版本升级时,回到旧问题的概率下降 |
| 鸿蒙实现一致性 | 校验并统一鸿蒙实现与原版库的行为表现 | 这是三方库移植最深的一层
:API 语义、回调时机、错误处理、返回值结构都要对齐,否则业务侧条件分支会走错 |
同一份 RN 代码在安卓/iOS/鸿蒙上分支逻辑一致,不用写 Platform.OS 特判 |
| 文档优化 | 完善使用文档,补充缺失描述、修正错误、更新版本约束 | 鸿蒙实现的差异化限制(不支持某参数、需额外权限、仅某 API 版本可用)必须显式写出来 | 接入时少猜、少试错,版本约束一眼可见 |
其中第 4 条值得单独说一句。
「鸿蒙实现一致性」是三方库移植里最容易被低估、也最贵的部分。 举个例子:某个图片裁剪库的 crop() 在安卓上失败时抛异常,鸿蒙实现却返回 null;业务代码写的是 try/catch,于是在鸿蒙上不但没崩,还在下一步拿到一个 null 继续往下跑,最终崩溃点出现在离现场几百行的位置。再比如回调时机——安卓在 onResume 之后回调、鸿蒙在 onPageShow 之前回调,业务侧的时序假设就会错位,表现为「偶现」的 UI 状态不一致。
这类问题不会因为「功能能跑」而被发现,只会因为逐接口比对被消除。本月把「一致性」列为专项方向,意味着适配工作从「实现功能」推进到了「实现语义」。
三、72 款库全景清单
安装方式统一:
npm install @react-native-ohos/<library-name>
说明:表中「框架版本」列为该库本次发布覆盖的 RNOH 框架版本线。源码地址大多位于 CPF-RN 组织,个别库(如 react-native-camera)源码仍在 GitHub 的 react-native-oh-library 组织下,已在表中标注实际地址。
UI 与视觉组件(19 款)
| 序号 | 包名 | 源码地址 | 框架版本 | 功能简介 |
|---|---|---|---|---|
| 1 | `@react-native-ohos/blur`[2] | CPF-RN/rntpc_react-native-blur[3] | 0.72 / 0.77 / 0.82 / 0.84 | 毛玻璃/模糊效果 |
| 2 | `@react-native-ohos/react-native-linear-gradient`[4] | CPF-RN/rntpc_react-native-linear-gradient[5] | 0.72 / 0.77 / 0.82 | 线性渐变组件 |
| 3 | `@react-native-ohos/masked-view`[6] | CPF-RN/rntpc_masked-view[7] | 0.77 / 0.82 / 0.84 | 遮罩视图 |
| 4 | `@react-native-ohos/react-native-fast-image`[8] | CPF-RN/rntpc_react-native-fast-image[9] | 0.72 / 0.77 | 高性能图片加载 |
| 5 | `@react-native-ohos/react-native-image-crop-picker`[10] | CPF-RN/rntpc_react-native-image-crop-picker[11] | 0.72 / 0.77 / 0.82 / 0.84 | 图片裁剪与选择 |
| 6 | `@react-native-ohos/react-native-image-sequence-2`[12] | CPF-RN/rntpc_react-native-image-sequence[13] | 0.72 / 0.77 / 0.82 / 0.84 | 图片序列动画 |
| 7 | `@react-native-ohos/react-native-image-marker`[14] | CPF-RN/rntpc_react-native-image-marker[15] | 0.77 / 0.82 / 0.84 | 图片标注/水印 |
| 8 | `@react-native-ohos/react-native-image-resizer`[16] | CPF-RN/rntpc_react-native-image-resizer[17] | 0.72 / 0.77 / 0.82 / 0.84 | 图片缩放压缩 |
| 9 | `@react-native-ohos/image-editor`[18] | CPF-RN/rntpc_react-native-image-editor[19] | 0.82 / 0.84 | 图片编辑 |
| 10 | `@react-native-ohos/react-native-photo-manipulator`[20] | CPF-RN/rntpc_react-native-photo-manipulator[21] | 0.72 / 0.77 / 0.82 | 图片操作处理 |
| 11 | `@react-native-ohos/react-native-syan-image-picker`[22] | CPF-RN/rntpc_react-native-syan-image-picker[23] | 0.72 / 0.77 / 0.82 | 图片选择器 |
| 12 | `@react-native-ohos/react-native-pager-view`[24] | CPF-RN/rntpc_react-native-pager-view[25] | 0.72 / 0.77 / 0.82 / 0.84 | 分页滑动视图 |
| 13 | `@react-native-ohos/react-native-screens`[26] | CPF-RN/rntpc_react-native-screens[27] | 0.72 / 0.77 / 0.82 | 屏幕导航管理 |
| 14 | `@react-native-ohos/flash-list`[28] | CPF-RN/rntpc_flash-list[29] | 0.77 | 高性能列表 |
| 15 | `@react-native-ohos/react-native-draggable-flatlist`[30] | CPF-RN/rntpc_react-native-draggable-flatlist[31] | 0.72 / 0.77 / 0.82 | 可拖拽列表 |
| 16 | `@react-native-ohos/react-native-keyboard-controller`[32] | CPF-RN/rntpc_react-native-keyboard-controller[33] | 0.72 / 0.77 / 0.82 / 0.84 | 键盘交互控制 |
| 17 | `@react-native-ohos/react-native-view-shot`[34] | CPF-RN/rntpc_react-native-view-shot[35] | 0.72 / 0.77 / 0.82 / 0.84 | 截图组件 |
| 18 | `@react-native-ohos/react-native-video`[36] | CPF-RN/rntpc_react-native-video[37] | 0.72 / 0.77 / 0.82 / 0.84 | 视频播放 |
| 19 | `@react-native-ohos/react-native-text-size`[38] | CPF-RN/rntpc_react-native-text-size[39] | 0.72 / 0.77 / 0.82 / 0.84 | 文本尺寸测量 |
相机与媒体采集(4 款)
| 序号 | 包名 | 源码地址 | 框架版本 | 功能简介 |
|---|---|---|---|---|
| 1 | `@react-native-ohos/react-native-camera`[40] | react-native-oh-library/react-native-camera[41] | 0.72 / 0.77 | 相机基础能力 |
| 2 | `@react-native-ohos/react-native-camera-kit`[42] | CPF-RN/rntpc_react-native-camera-kit[43] | 0.84 | 相机增强套件 |
| 3 | `@react-native-ohos/react-native-vision-camera`[44] | CPF-RN/rntpc_react-native-vision-camera[45] | 0.72 / 0.77 / 0.82 / 0.84 | 高级相机框架 |
| 4 | `@react-native-ohos/camera-roll`[46] | CPF-RN/rntpc_react-native-cameraroll[47] | 0.72 / 0.77 | 相册访问 |
音频与录制(3 款)
| 序号 | 包名 | 源码地址 | 框架版本 | 功能简介 |
|---|---|---|---|---|
| 1 | `@react-native-ohos/react-native-sound`[48] | CPF-RN/rntpc_react-native-sound[49] | 0.82 / 0.84 | 音频播放 |
| 2 | `@react-native-ohos/react-native-audio`[50] | CPF-RN/rntpc_react-native-audio[51] | 0.72 / 0.77 / 0.82 | 音频能力 |
| 3 | `@react-native-ohos/react-native-audio-recorder-player`[52] | CPF-RN/rntpc_react-native-audio-recorder-player[53] | 0.72 / 0.77 / 0.82 / 0.84 | 录音与播放 |
文件与存储(8 款)
| 序号 | 包名 | 源码地址 | 框架版本 | 功能简介 |
|---|---|---|---|---|
| 1 | `@react-native-ohos/react-native-sqlite-storage`[54] | CPF-RN/rntpc_react-native-sqlite-storage[55] | 0.72 / 0.77 / 0.82 / 0.84 | SQLite 数据库 |
| 2 | `@react-native-ohos/react-native-mmkv`[56] | CPF-RN/rntpc_react-native-mmkv[57] | 0.84 | 高性能键值存储 |
| 3 | `@react-native-ohos/react-native-mmkv-storage`[58] | CPF-RN/rntpc_react-native-mmkv-storage[59] | 0.72 / 0.77 / 0.82 / 0.84 | MMKV 存储封装 |
| 4 | `@react-native-ohos/async-storage`[60] | CPF-RN/rntpc_async-storage[61] | 0.72 / 0.77 / 0.82 / 0.84 | 异步存储 |
| 5 | `@react-native-ohos/react-native-fs`[62] | CPF-RN/rntpc_react-native-fs[63] | 0.72 / 0.77 / 0.82 / 0.84 | 文件系统操作 |
| 6 | `@react-native-ohos/react-native-blob-util`[64] | CPF-RN/rntpc_react-native-blob-util[65] | 0.72 / 0.77 / 0.82 / 0.84 | Blob 数据处理 |
| 7 | `@react-native-ohos/react-native-document-picker`[66] | CPF-RN/rntpc_react-native-document-picker[67] | 0.82 | 文档选择器 |
| 8 | `@react-native-ohos/react-native-zip-archive`[68] | CPF-RN/rntpc_react-native-zip-archive[69] | 0.72 / 0.77 / 0.82 | ZIP 压缩/解压 |
网络与通信(3 款)
| 序号 | 包名 | 源码地址 | 框架版本 | 功能简介 |
|---|---|---|---|---|
| 1 | `@react-native-ohos/netinfo`[70] | CPF-RN/rntpc_react-native-netinfo[71] | 0.72 / 0.77 / 0.82 / 0.84 | 网络状态监听 |
| 2 | `@react-native-ohos/cookies`[72] | CPF-RN/rntpc_cookies[73] | 0.72 / 0.77 | Cookie 管理 |
| 3 | `@react-native-ohos/react-native-webrtc`[74] | CPF-RN/rntpc_react-native-webrtc[75] | 0.72 / 0.77 / 0.82 | WebRTC 实时通信 |
定位与地图(3 款)
| 序号 | 包名 | 源码地址 | 框架版本 | 功能简介 |
|---|---|---|---|---|
| 1 | `@react-native-ohos/geolocation`[76] | CPF-RN/rntpc_react-native-geolocation[77] | 0.72 / 0.77 / 0.82 / 0.84 | 地理定位 |
| 2 | `@react-native-ohos/react-native-maps`[78] | CPF-RN/rntpc_react-native-maps[79] | 0.84 | 地图组件 |
| 3 | `@react-native-ohos/react-native-amap3d`[80] | CPF-RN/rntpc_react-native-amap3d[81] | 0.72 / 0.77 / 0.82 / 0.84 | 高德 3D 地图 |
设备与系统能力(7 款)
| 序号 | 包名 | 源码地址 | 框架版本 | 功能简介 |
|---|---|---|---|---|
| 1 | `@react-native-ohos/react-native-device-info`[82] | CPF-RN/rntpc_react-native-device-info[83] | 0.72 / 0.77 / 0.82 / 0.84 | 设备信息 |
| 2 | `@react-native-ohos/react-native-system-setting`[84] | CPF-RN/rntpc_react-native-system-setting[85] | 0.72 / 0.77 / 0.82 / 0.84 | 系统设置 |
| 3 | `@react-native-ohos/react-native-haptic-feedback`[86] | CPF-RN/rntpc_react-native-haptic-feedback[87] | 0.72 | 触觉反馈/振动 |
| 4 | `@react-native-ohos/react-native-permissions`[88] | CPF-RN/rntpc_react-native-permissions[89] | 0.72 / 0.77 / 0.82 / 0.84 | 权限管理 |
| 5 | `@react-native-ohos/react-native-sensors`[90] | CPF-RN/rntpc_react-native-sensors[91] | 0.84 | 传感器访问 |
| 6 | `@react-native-ohos/react-native-restart`[92] | CPF-RN/rntpc_react-native-restart[93] | 0.84 | 应用重启 |
| 7 | `@react-native-ohos/react-native-orientation-locker`[94] | CPF-RN/rntpc_react-native-orientation-locker[95] | 0.72 / 0.77 / 0.82 / 0.84 | 屏幕方向锁定 |
UI 控件(6 款)
| 序号 | 包名 | 源码地址 | 框架版本 | 功能简介 |
|---|---|---|---|---|
| 1 | `@react-native-ohos/picker`[96] | CPF-RN/rntpc_picker[97] | 0.72 / 0.84 | 选择器组件 |
| 2 | `@react-native-ohos/datetimepicker`[98] | CPF-RN/rntpc_datetimepicker[99] | 0.84 | 日期时间选择器 |
| 3 | `@react-native-ohos/checkbox`[100] | CPF-RN/rntpc_react-native-checkbox[101] | 0.82 / 0.84 | 复选框 |
| 4 | `@react-native-ohos/slider`[102] | CPF-RN/rntpc_react-native-slider[103] | 0.84 | 滑动条 |
| 5 | `@react-native-ohos/react-native-slider`[104] | CPF-RN/jeanregisser-react-native-slider[105] | 0.77 / 0.82 / 0.84 | 滑块组件 |
| 6 | `@react-native-ohos/progress-view`[106] | CPF-RN/rntpc_progress-view[107] | 0.72 / 0.82 / 0.84 | 进度视图 |
安全与加密(1 款)
| 序号 | 包名 | 源码地址 | 框架版本 | 功能简介 |
|---|---|---|---|---|
| 1 | `@react-native-ohos/react-native-rsa-native`[108] | CPF-RN/react-native-rsa-native[109] | 0.72 | RSA 加密/解密 |
推送与后台任务(2 款)
| 序号 | 包名 | 源码地址 | 框架版本 | 功能简介 |
|---|---|---|---|---|
| 1 | `@react-native-ohos/push-notification-ios`[110] | CPF-RN/rntpc_ios[111] | 0.82 / 0.84 | 推送通知 |
| 2 | `@react-native-ohos/react-native-background-timer`[112] | CPF-RN/rntpc_react-native-background-timer[113] | 0.82 / 0.84 | 后台定时器 |
社交与分享(2 款)
| 序号 | 包名 | 源码地址 | 框架版本 | 功能简介 |
|---|---|---|---|---|
| 1 | `@react-native-ohos/react-native-share`[114] | CPF-RN/rntpc_react-native-share[115] | 0.72 / 0.82 | 内容分享 |
| 2 | `@react-native-ohos/react-native-wechat-lib`[116] | CPF-RN/rntpc_react-native-wechat-lib[117] | 0.72 / 0.77 / 0.82 / 0.84 | 微信 SDK 集成 |
动画与特效(1 款)
| 序号 | 包名 | 源码地址 | 框架版本 | 功能简介 |
|---|---|---|---|---|
| 1 | `@react-native-ohos/lottie-react-native`[118] | CPF-RN/rntpc_lottie-react-native[119] | 0.72 / 0.77 / 0.82 | Lottie 动画 |
其他实用工具(13 款)
| 序号 | 包名 | 源码地址 | 框架版本 | 功能简介 |
|---|---|---|---|---|
| 1 | `@react-native-ohos/react-native-webview`[120] | CPF-RN/rntpc_react-native-webview[121] | 0.77 / 0.82 / 0.84 | WebView 组件 |
| 2 | `@react-native-ohos/react-native-splash-screen`[122] | CPF-RN/rntpc_react-native-splash-screen[123] | 0.72 / 0.77 / 0.82 / 0.84 | 启动屏 |
| 3 | `@react-native-ohos/react-native-signature-capture`[124] | CPF-RN/rntpc_react-native-signature-capture[125] | 0.72 / 0.77 / 0.82 | 签名采集 |
| 4 | `@react-native-ohos/react-native-pdf`[126] | CPF-RN/rntpc_react-native-pdf[127] | 0.72 / 0.77 / 0.82 / 0.84 | PDF 文档查看 |
| 5 | `@react-native-ohos/react-native-config`[128] | CPF-RN/rntpc_react-native-config[129] | 0.82 / 0.84 | 环境配置管理 |
| 6 | `@react-native-ohos/react-native-localize`[130] | CPF-RN/rntpc_react-native-localize[131] | 0.72 / 0.77 / 0.82 / 0.84 | 本地化信息 |
| 7 | `@react-native-ohos/react-native-safe-area-context`[132] | CPF-RN/rntpc_react-native-safe-area-context[133] | 0.77 / 0.82 / 0.84 | 安全区域 |
| 8 | `@react-native-ohos/clipboard`[134] | CPF-RN/rntpc_clipboard[135] | 0.72 / 0.77 | 剪贴板 |
| 9 | `@react-native-ohos/react-native-nfc-manager`[136] | CPF-RN/rntpc_react-native-nfc-manager[137] | 0.72 / 0.77 / 0.82 / 0.84 | NFC 读写 |
| 10 | `@react-native-ohos/jpush-react-native`[138] | CPF-RN/rntpc_jpush-react-native[139] | 0.72 / 0.77 / 0.82 / 0.84 | 极光推送 |
| 11 | `@react-native-ohos/react-native-default-preference`[140] | CPF-RN/rntpc_react-native-default-preference[141] | 0.72 / 0.77 / 0.82 | 默认偏好设置 |
| 12 | `@react-native-ohos/react-native-smartrefreshlayout`[142] | CPF-RN/rntpc_react-native-SmartRefreshLayout[143] | 0.72 / 0.82 / 0.84 | 智能刷新布局 |
| 13 | `@react-native-ohos/react-native-date-picker`[144] | CPF-RN/rntpc_react-native-datepicker[145] | 0.82 / 0.84 | 日期选择器 |
四、从 72 行清单里读出的三个结论
把上面的表格按「框架版本」列做一次统计,能看出不少东西:
结论 1:0.82 是覆盖面最广的一条线,0.84 已基本追平
| 框架版本线 | 覆盖库数量 | 占 72 款比例 |
|---|---|---|
| 0.72 | 51 | 71% |
| 0.77 | 51 | 71% |
| 0.82 | 56 | 78% |
| 0.84 | 51 | 71% |
统计口径:某库的「框架版本」列包含该版本线即计入,一库可计入多条线。
怎么解读:0.82 覆盖面第一(56 款)说明它是当前的「生态重心」——绝大多数库都优先在这条线上做了验证。而 0.84 作为最新线已经达到 51 款、与 0.72/0.77 持平并逼近 0.82,说明社区并没有把新版本当成「先适配几个重要库再说」,而是在同步推进。
对你的实际意义:如果你的项目还在 0.72/0.77,升级前先确认你要用的那几个库在 0.82/0.84 上是否已覆盖——差 5~6 款听起来不多,但踩中的那个往往就是你项目里最离不开的那个。
结论 2:约 40% 的库做到了四线全绿
有 29 款库同时支持 0.72 / 0.77 / 0.82 / 0.84 全部四条版本线,占 40%。
这批库是生态里的「压舱石」——它们基本覆盖了任何 RN 应用都绕不开的基础能力:存储(async-storage、sqlite-storage、mmkv-storage)、文件(fs、blob-util)、设备(device-info、permissions、orientation-locker、system-setting)、网络(netinfo)、定位与地图(geolocation、amap3d)、图像与视觉(image-crop-picker、image-resizer、blur、image-sequence-2)、媒体(video、audio-recorder-player、vision-camera)、UI(pager-view、keyboard-controller、view-shot、text-size)、工具(splash-screen、pdf、localize、nfc-manager、jpush)、社交(wechat-lib)。
这 29 款可以理解为「跨版本安全区」:无论你的项目锚在哪条 RN 线上,它们都能用,升级 RNOH 框架时也不必为此改代码。
结论 3:11 款库只支持单一版本线,都是「有原因」的
| 仅支持的版本线 | 库 |
|---|---|
| 0.72 | react-native-haptic-feedback
、react-native-rsa-native |
| 0.77 | flash-list |
| 0.82 | react-native-document-picker |
| 0.84 | react-native-camera-kit
、react-native-mmkv、react-native-maps、react-native-sensors、react-native-restart、datetimepicker、slider |
单版本线不等于「质量差」,通常是三类原因:新库刚落地(先在最活跃的线上验证,如 mmkv、maps、camera-kit)、上游库自身版本耦合(如 flash-list 对 RN 版本敏感)、依赖较新的鸿蒙 API(低版本 SDK 上无法实现)。
选型提醒:这 11 款在接入前务必确认你的 RNOH 框架版本正好落在它支持的那条线上,否则会遇到「装上了但编译不过 / 运行时不回调」这类最难排查的问题。
五、场景选型速查:什么需求找什么库
72 款库摊开看容易晕,按「我要做什么」反查更实用:
| 我要做的功能 | 首选库 | 可搭配 |
|---|---|---|
| 长列表 / 无限滚动 | flash-list
(0.77) |
react-native-smartrefreshlayout
、draggable-flatlist |
| 页面导航与手势返回 | react-native-screens | react-native-safe-area-context
、pager-view |
| 内嵌 H5 / 富文本 | react-native-webview | react-native-cookies
(登录态) |
| 文档阅读(PDF/合同/发票) | react-native-pdf | react-native-document-picker
、blob-util |
| 表单与输入体验 | react-native-keyboard-controller | datetimepicker
、picker、checkbox、slider |
| 头像上传 / 图片流水线 | react-native-image-crop-picker | image-resizer
、image-marker、photo-manipulator、syan-image-picker |
| 扫码 / 拍照识别 | react-native-vision-camera | react-native-camera-kit
、camera-roll |
| 短视频与音频播录 | react-native-video
/ audio-recorder-player |
react-native-sound
、react-native-audio |
| 实时音视频通话 | react-native-webrtc | permissions
、orientation-locker |
| 本地缓存与离线数据 | react-native-mmkv
(0.84) / async-storage |
sqlite-storage
、fs、zip-archive |
| 地图与 LBS | react-native-maps
(0.84) / amap3d |
geolocation |
| 微信登录 / 分享 / 支付前置 | react-native-wechat-lib | react-native-share
、clipboard |
| 消息推送 | jpush-react-native | push-notification-ios
、background-timer |
| 卡片 / 门禁 / 一碰传 | react-native-nfc-manager | device-info
、permissions |
| 视觉特效与动效 | react-native-blur
、lottie-react-native |
linear-gradient
、masked-view、image-sequence-2 |
| 数据安全 | react-native-rsa-native | mmkv
(加密存储)、react-native-config(密钥分环境) |
| 截图 / 分享海报 | react-native-view-shot | image-marker
、share |
六、升级实操:五步走,别跳步
第 1 步:先确认你的框架版本线(最容易跳过、后果最严重)
三方库的鸿蒙实现依赖 RNOH 桥接层的 C-API 与 TurboModule 接口,版本线错配是「能 install、不能跑」的头号原因。先查你工程里的 RNOH 版本:
# 查看当前 RNOH / react-native 版本
npm ls react-native @react-native-oh/react-native-harmony
把结果映射到版本线(0.72 / 0.77 / 0.82 / 0.84),再回到第三节表格里确认目标库是否覆盖这条线。不要跨版本线强行安装。
第 2 步:更新依赖
# 升级单个库
npm install @react-native-ohos/<library-name>
# 批量升级全部 @react-native-ohos 依赖
npx npm-check-updates -u -f “@react-native-ohos/*” && npm install
也可以直接改 package.json 里的版本号,然后:
npm install
建议:一次只升一类库(先存储、再 UI、最后媒体相机)。摄影机、音视频类库的原生依赖较重,混在一批里升,出问题时无法二分定位。
第 3 步:读 CHANGELOG,找 Breaking Changes
公告明确提示:各仓库具体的优化内容与变更明细,请参阅对应仓库的 Release Note 和 CHANGELOG。
质量专项虽然以「不破坏接口」为目标,但为了对齐上游行为,个别库可能会修正过去「实现错了但大家已经绕过去了」的地方——这类修正对老项目来说是隐性 Breaking Change。先读再升。
第 4 步:含原生组件的库需要重新生成桥接代码
RNOH 采用 Codegen 机制,TurboModule / Fabric 组件的桥接代码是由接口定义生成的。升级了带原生实现的库之后,光 npm install 不够——需要重新执行 Codegen 让桥接层与新的接口定义对齐,否则会出现方法找不到、参数类型不匹配等运行期错误。
纯 JS 的库(dayjs、axios、redux 这一层)不受影响,装了就能用。
第 5 步:在 DevEco Studio 中重新编译并在真机验证
公告要求:升级后请在 DevEco Studio 中重新编译工程,并运行自动化测试与手动验证。
建议按这张清单走一遍:
| 检查项 | 为什么要查 |
|---|---|
| 增量编译产物是否被清理 | 旧的 .har / 中间产物残留会掩盖真实问题,让人误判「升级无效」 |
| 原生依赖(第三方 SDK)是否同步更新 | 如微信、极光、高德类库,JS 包与原生 SDK 版本需配套 |
| Codegen 是否执行成功 | 失败时往往只是一条 warning,但运行期才炸 |
| 真机跑核心链路 | 模拟器与真机在相机、NFC、传感器、定位等能力上差异很大 |
| 重复进入/退出页面 20 次以上 | 本月的「稳定性增强」集中在边界路径,反复进出是验证回调与释放是否正确的有效方式 |
| 异常入参验证 | 空数组、空字符串、超大图片、断网后重试——这类场景正是本月专项覆盖重点 |
七、兼容性矩阵
| 项 | 要求 |
|---|---|
| DevEco Studio | 建议 6.0.2 Release 及以上 |
| HarmonyOS SDK | API 12 及以上;部分库要求 API 14 及以上(以各库文档为准) |
| React Native | 支持 0.72 / 0.77 / 0.82 / 0.84 等主流版本框架 |
| 包管理 | npm;包名前缀统一为 @react-native-ohos/ |
八、反馈与共建:生态的下一个 72 款靠谁
遇到问题的正确路径
| 目的 | 去哪里 |
|---|---|
| 查这个库怎么用 | CPF-RN/usage-docs[146] (三方库使用文档中心,含鸿蒙化库对照表与 JS 库清单) |
| 查这个库改了什么 | 对应仓库的 Release Note / CHANGELOG |
| 报 Bug / 提需求 | 在对应仓库提交 Issue(不要提到组织层,否则定位成本翻倍) |
| 了解框架本身 | CPF-RN/ohos_react_native[147] |
| 让 AI 帮你写 RNOH 代码 | CPF-RN/skills[148] (npx @react-native-oh/kit add) |
四类可以直接上手贡献的事
公告最后给出的四个共建方向,按门槛从低到高排列:
- 🚀 适配新的 React Native 三方库 —— 在 Issue 中认领待适配任务。这是对生态增量最大的一件事:每多一款库,就少一批开发者被迫自己写原生代码。
- 📚 完善使用文档 —— 门槛最低,价值却最直接。尤其「这个参数在鸿蒙上不支持」这类一句话说明,能省掉后来者半天的试错。
- 🔧 提交 Bug 修复与功能增强 —— 在对应仓库提交 PR。三方库的鸿蒙实现通常是原库的一份 patch 化移植,改动面可控。
- 💬 分享使用经验 —— 撰写技术博客或在社区答疑。本月质量专项里的很多修复,源头就是某位开发者一句「我这边复现了,这样能绕过」。
九、一页速查
| 资源 | 链接 |
|---|---|
| 本次发布公告(原文) | https://atomgit.com/org/CPF-RN/discussions/19 |
| CPF-RN 组织主页 | https://atomgit.com/CPF-RN |
| 三方库使用文档中心 | https://atomgit.com/CPF-RN/usage-docs |
| RNOH 框架本体 | https://atomgit.com/CPF-RN/ohos_react_native |
| RNOH AI Agent 技能库 | https://atomgit.com/CPF-RN/skills |
| 鸿蒙特色能力封装 | https://atomgit.com/CPF-RN/rn_ohfeatures |
| npm 包命名空间 | @react-native-ohos/ |
升级三条硬规矩:
- 框架版本线必须对齐——0.72/0.77/0.82/0.84 别跨界。
- CHANGELOG 必读——质量专项里的「行为对齐」对老项目等于隐性 Breaking Change。
- 真机跑核心链路——相机、NFC、传感器、定位在模拟器上验不出真问题。
参考资料:
[1] CPF-RN 组织讨论 #19 · React Native OpenHarmony(RNOH)三方库版本发布公告: https://atomgit.com/org/CPF-RN/discussions/19
[2] @react-native-ohos/blur: https://www.npmjs.com/package/@react-native-ohos/blur
[3] CPF-RN/rntpc_react-native-blur: https://atomgit.com/CPF-RN/rntpc_react-native-blur
[4] @react-native-ohos/react-native-linear-gradient: https://www.npmjs.com/package/@react-native-ohos/react-native-linear-gradient
[5] CPF-RN/rntpc_react-native-linear-gradient: https://atomgit.com/CPF-RN/rntpc_react-native-linear-gradient
[6] @react-native-ohos/masked-view: https://www.npmjs.com/package/@react-native-ohos/masked-view
[7] CPF-RN/rntpc_masked-view: https://atomgit.com/CPF-RN/rntpc_masked-view
[8] @react-native-ohos/react-native-fast-image: https://www.npmjs.com/package/@react-native-ohos/react-native-fast-image
[9] CPF-RN/rntpc_react-native-fast-image: https://atomgit.com/CPF-RN/rntpc_react-native-fast-image
[10] @react-native-ohos/react-native-image-crop-picker: https://www.npmjs.com/package/@react-native-ohos/react-native-image-crop-picker
[11] CPF-RN/rntpc_react-native-image-crop-picker: https://atomgit.com/CPF-RN/rntpc_react-native-image-crop-picker
[12] @react-native-ohos/react-native-image-sequence-2: https://www.npmjs.com/package/@react-native-ohos/react-native-image-sequence-2
[13] CPF-RN/rntpc_react-native-image-sequence: https://atomgit.com/CPF-RN/rntpc_react-native-image-sequence
[14] @react-native-ohos/react-native-image-marker: https://www.npmjs.com/package/@react-native-ohos/react-native-image-marker
[15] CPF-RN/rntpc_react-native-image-marker: https://atomgit.com/CPF-RN/rntpc_react-native-image-marker
[16] @react-native-ohos/react-native-image-resizer: https://www.npmjs.com/package/@react-native-ohos/react-native-image-resizer
[17] CPF-RN/rntpc_react-native-image-resizer: https://atomgit.com/CPF-RN/rntpc_react-native-image-resizer
[18] @react-native-ohos/image-editor: https://www.npmjs.com/package/@react-native-ohos/image-editor
[19] CPF-RN/rntpc_react-native-image-editor: https://atomgit.com/CPF-RN/rntpc_react-native-image-editor
[20] @react-native-ohos/react-native-photo-manipulator: https://www.npmjs.com/package/@react-native-ohos/react-native-photo-manipulator
[21] CPF-RN/rntpc_react-native-photo-manipulator: https://atomgit.com/CPF-RN/rntpc_react-native-photo-manipulator
[22] @react-native-ohos/react-native-syan-image-picker: https://www.npmjs.com/package/@react-native-ohos/react-native-syan-image-picker
[23] CPF-RN/rntpc_react-native-syan-image-picker: https://atomgit.com/CPF-RN/rntpc_react-native-syan-image-picker
[24] @react-native-ohos/react-native-pager-view: https://www.npmjs.com/package/@react-native-ohos/react-native-pager-view
[25] CPF-RN/rntpc_react-native-pager-view: https://atomgit.com/CPF-RN/rntpc_react-native-pager-view
[26] @react-native-ohos/react-native-screens: https://www.npmjs.com/package/@react-native-ohos/react-native-screens
[27] CPF-RN/rntpc_react-native-screens: https://atomgit.com/CPF-RN/rntpc_react-native-screens
[28] @react-native-ohos/flash-list: https://www.npmjs.com/package/@react-native-ohos/flash-list
[29] CPF-RN/rntpc_flash-list: https://atomgit.com/CPF-RN/rntpc_flash-list
[30] @react-native-ohos/react-native-draggable-flatlist: https://www.npmjs.com/package/@react-native-ohos/react-native-draggable-flatlist
[31] CPF-RN/rntpc_react-native-draggable-flatlist: https://atomgit.com/CPF-RN/rntpc_react-native-draggable-flatlist
[32] @react-native-ohos/react-native-keyboard-controller: https://www.npmjs.com/package/@react-native-ohos/react-native-keyboard-controller
[33] CPF-RN/rntpc_react-native-keyboard-controller: https://atomgit.com/CPF-RN/rntpc_react-native-keyboard-controller
[34] @react-native-ohos/react-native-view-shot: https://www.npmjs.com/package/@react-native-ohos/react-native-view-shot
[35] CPF-RN/rntpc_react-native-view-shot: https://atomgit.com/CPF-RN/rntpc_react-native-view-shot
[36] @react-native-ohos/react-native-video: https://www.npmjs.com/package/@react-native-ohos/react-native-video
[37] CPF-RN/rntpc_react-native-video: https://atomgit.com/CPF-RN/rntpc_react-native-video
[38] @react-native-ohos/react-native-text-size: https://www.npmjs.com/package/@react-native-ohos/react-native-text-size
[39] CPF-RN/rntpc_react-native-text-size: https://atomgit.com/CPF-RN/rntpc_react-native-text-size
[40] @react-native-ohos/react-native-camera: https://www.npmjs.com/package/@react-native-ohos/react-native-camera
[41] react-native-oh-library/react-native-camera: https://github.com/react-native-oh-library/react-native-camera
[42] @react-native-ohos/react-native-camera-kit: https://www.npmjs.com/package/@react-native-ohos/react-native-camera-kit
[43] CPF-RN/rntpc_react-native-camera-kit: https://atomgit.com/CPF-RN/rntpc_react-native-camera-kit
[44] @react-native-ohos/react-native-vision-camera: https://www.npmjs.com/package/@react-native-ohos/react-native-vision-camera
[45] CPF-RN/rntpc_react-native-vision-camera: https://atomgit.com/CPF-RN/rntpc_react-native-vision-camera
[46] @react-native-ohos/camera-roll: https://www.npmjs.com/package/@react-native-ohos/camera-roll
[47] CPF-RN/rntpc_react-native-cameraroll: https://atomgit.com/CPF-RN/rntpc_react-native-cameraroll
[48] @react-native-ohos/react-native-sound: https://www.npmjs.com/package/@react-native-ohos/react-native-sound
[49] CPF-RN/rntpc_react-native-sound: https://atomgit.com/CPF-RN/rntpc_react-native-sound
[50] @react-native-ohos/react-native-audio: https://www.npmjs.com/package/@react-native-ohos/react-native-audio
[51] CPF-RN/rntpc_react-native-audio: https://atomgit.com/CPF-RN/rntpc_react-native-audio
[52] @react-native-ohos/react-native-audio-recorder-player: https://www.npmjs.com/package/@react-native-ohos/react-native-audio-recorder-player
[53] CPF-RN/rntpc_react-native-audio-recorder-player: https://atomgit.com/CPF-RN/rntpc_react-native-audio-recorder-player
[54] @react-native-ohos/react-native-sqlite-storage: https://www.npmjs.com/package/@react-native-ohos/react-native-sqlite-storage
[55] CPF-RN/rntpc_react-native-sqlite-storage: https://atomgit.com/CPF-RN/rntpc_react-native-sqlite-storage
[56] @react-native-ohos/react-native-mmkv: https://www.npmjs.com/package/@react-native-ohos/react-native-mmkv
[57] CPF-RN/rntpc_react-native-mmkv: https://atomgit.com/CPF-RN/rntpc_react-native-mmkv
[58] @react-native-ohos/react-native-mmkv-storage: https://www.npmjs.com/package/@react-native-ohos/react-native-mmkv-storage
[59] CPF-RN/rntpc_react-native-mmkv-storage: https://atomgit.com/CPF-RN/rntpc_react-native-mmkv-storage
[60] @react-native-ohos/async-storage: https://www.npmjs.com/package/@react-native-ohos/async-storage
[61] CPF-RN/rntpc_async-storage: https://atomgit.com/CPF-RN/rntpc_async-storage
[62] @react-native-ohos/react-native-fs: https://www.npmjs.com/package/@react-native-ohos/react-native-fs
[63] CPF-RN/rntpc_react-native-fs: https://atomgit.com/CPF-RN/rntpc_react-native-fs
[64] @react-native-ohos/react-native-blob-util: https://www.npmjs.com/package/@react-native-ohos/react-native-blob-util
[65] CPF-RN/rntpc_react-native-blob-util: https://atomgit.com/CPF-RN/rntpc_react-native-blob-util
[66] @react-native-ohos/react-native-document-picker: https://www.npmjs.com/package/@react-native-ohos/react-native-document-picker
[67] CPF-RN/rntpc_react-native-document-picker: https://atomgit.com/CPF-RN/rntpc_react-native-document-picker
[68] @react-native-ohos/react-native-zip-archive: https://www.npmjs.com/package/@react-native-ohos/react-native-zip-archive
[69] CPF-RN/rntpc_react-native-zip-archive: https://atomgit.com/CPF-RN/rntpc_react-native-zip-archive
[70] @react-native-ohos/netinfo: https://www.npmjs.com/package/@react-native-ohos/netinfo
[71] CPF-RN/rntpc_react-native-netinfo: https://atomgit.com/CPF-RN/rntpc_react-native-netinfo
[72] @react-native-ohos/cookies: https://www.npmjs.com/package/@react-native-ohos/cookies
[73] CPF-RN/rntpc_cookies: https://atomgit.com/CPF-RN/rntpc_cookies
[74] @react-native-ohos/react-native-webrtc: https://www.npmjs.com/package/@react-native-ohos/react-native-webrtc
[75] CPF-RN/rntpc_react-native-webrtc: https://atomgit.com/CPF-RN/rntpc_react-native-webrtc
[76] @react-native-ohos/geolocation: https://www.npmjs.com/package/@react-native-ohos/geolocation
[77] CPF-RN/rntpc_react-native-geolocation: https://atomgit.com/CPF-RN/rntpc_react-native-geolocation
[78] @react-native-ohos/react-native-maps: https://www.npmjs.com/package/@react-native-ohos/react-native-maps
[79] CPF-RN/rntpc_react-native-maps: https://atomgit.com/CPF-RN/rntpc_react-native-maps
[80] @react-native-ohos/react-native-amap3d: https://www.npmjs.com/package/@react-native-ohos/react-native-amap3d
[81] CPF-RN/rntpc_react-native-amap3d: https://atomgit.com/CPF-RN/rntpc_react-native-amap3d
[82] @react-native-ohos/react-native-device-info: https://www.npmjs.com/package/@react-native-ohos/react-native-device-info
[83] CPF-RN/rntpc_react-native-device-info: https://atomgit.com/CPF-RN/rntpc_react-native-device-info
[84] @react-native-ohos/react-native-system-setting: https://www.npmjs.com/package/@react-native-ohos/react-native-system-setting
[85] CPF-RN/rntpc_react-native-system-setting: https://atomgit.com/CPF-RN/rntpc_react-native-system-setting
[86] @react-native-ohos/react-native-haptic-feedback: https://www.npmjs.com/package/@react-native-ohos/react-native-haptic-feedback
[87] CPF-RN/rntpc_react-native-haptic-feedback: https://atomgit.com/CPF-RN/rntpc_react-native-haptic-feedback
[88] @react-native-ohos/react-native-permissions: https://www.npmjs.com/package/@react-native-ohos/react-native-permissions
[89] CPF-RN/rntpc_react-native-permissions: https://atomgit.com/CPF-RN/rntpc_react-native-permissions
[90] @react-native-ohos/react-native-sensors: https://www.npmjs.com/package/@react-native-ohos/react-native-sensors
[91] CPF-RN/rntpc_react-native-sensors: https://atomgit.com/CPF-RN/rntpc_react-native-sensors
[92] @react-native-ohos/react-native-restart: https://www.npmjs.com/package/@react-native-ohos/react-native-restart
[93] CPF-RN/rntpc_react-native-restart: https://atomgit.com/CPF-RN/rntpc_react-native-restart
[94] @react-native-ohos/react-native-orientation-locker: https://www.npmjs.com/package/@react-native-ohos/react-native-orientation-locker
[95] CPF-RN/rntpc_react-native-orientation-locker: https://atomgit.com/CPF-RN/rntpc_react-native-orientation-locker
[96] @react-native-ohos/picker: https://www.npmjs.com/package/@react-native-ohos/picker
[97] CPF-RN/rntpc_picker: https://atomgit.com/CPF-RN/rntpc_picker
[98] @react-native-ohos/datetimepicker: https://www.npmjs.com/package/@react-native-ohos/datetimepicker
[99] CPF-RN/rntpc_datetimepicker: https://atomgit.com/CPF-RN/rntpc_datetimepicker
[100] @react-native-ohos/checkbox: https://www.npmjs.com/package/@react-native-ohos/checkbox
[101] CPF-RN/rntpc_react-native-checkbox: https://atomgit.com/CPF-RN/rntpc_react-native-checkbox
[102] @react-native-ohos/slider: https://www.npmjs.com/package/@react-native-ohos/slider
[103] CPF-RN/rntpc_react-native-slider: https://atomgit.com/CPF-RN/rntpc_react-native-slider
[104] @react-native-ohos/react-native-slider: https://www.npmjs.com/package/@react-native-ohos/react-native-slider
[105] CPF-RN/jeanregisser-react-native-slider: https://atomgit.com/CPF-RN/jeanregisser-react-native-slider
[106] @react-native-ohos/progress-view: https://www.npmjs.com/package/@react-native-ohos/progress-view
[107] CPF-RN/rntpc_progress-view: https://atomgit.com/CPF-RN/rntpc_progress-view
[108] @react-native-ohos/react-native-rsa-native: https://www.npmjs.com/package/@react-native-ohos/react-native-rsa-native
[109] CPF-RN/react-native-rsa-native: https://atomgit.com/CPF-RN/react-native-rsa-native
[110] @react-native-ohos/push-notification-ios: https://www.npmjs.com/package/@react-native-ohos/push-notification-ios
[111] CPF-RN/rntpc_ios: https://atomgit.com/CPF-RN/rntpc_ios
[112] @react-native-ohos/react-native-background-timer: https://www.npmjs.com/package/@react-native-ohos/react-native-background-timer
[113] CPF-RN/rntpc_react-native-background-timer: https://atomgit.com/CPF-RN/rntpc_react-native-background-timer
[114] @react-native-ohos/react-native-share: https://www.npmjs.com/package/@react-native-ohos/react-native-share
[115] CPF-RN/rntpc_react-native-share: https://atomgit.com/CPF-RN/rntpc_react-native-share
[116] @react-native-ohos/react-native-wechat-lib: https://www.npmjs.com/package/@react-native-ohos/react-native-wechat-lib
[117] CPF-RN/rntpc_react-native-wechat-lib: https://atomgit.com/CPF-RN/rntpc_react-native-wechat-lib
[118] @react-native-ohos/lottie-react-native: https://www.npmjs.com/package/@react-native-ohos/lottie-react-native
[119] CPF-RN/rntpc_lottie-react-native: https://atomgit.com/CPF-RN/rntpc_lottie-react-native
[120] @react-native-ohos/react-native-webview: https://www.npmjs.com/package/@react-native-ohos/react-native-webview
[121] CPF-RN/rntpc_react-native-webview: https://atomgit.com/CPF-RN/rntpc_react-native-webview
[122] @react-native-ohos/react-native-splash-screen: https://www.npmjs.com/package/@react-native-ohos/react-native-splash-screen
[123] CPF-RN/rntpc_react-native-splash-screen: https://atomgit.com/CPF-RN/rntpc_react-native-splash-screen
[124] @react-native-ohos/react-native-signature-capture: https://www.npmjs.com/package/@react-native-ohos/react-native-signature-capture
[125] CPF-RN/rntpc_react-native-signature-capture: https://atomgit.com/CPF-RN/rntpc_react-native-signature-capture
[126] @react-native-ohos/react-native-pdf: https://www.npmjs.com/package/@react-native-ohos/react-native-pdf
[127] CPF-RN/rntpc_react-native-pdf: https://atomgit.com/CPF-RN/rntpc_react-native-pdf
[128] @react-native-ohos/react-native-config: https://www.npmjs.com/package/@react-native-ohos/react-native-config
[129] CPF-RN/rntpc_react-native-config: https://atomgit.com/CPF-RN/rntpc_react-native-config
[130] @react-native-ohos/react-native-localize: https://www.npmjs.com/package/@react-native-ohos/react-native-localize
[131] CPF-RN/rntpc_react-native-localize: https://atomgit.com/CPF-RN/rntpc_react-native-localize
[132] @react-native-ohos/react-native-safe-area-context: https://www.npmjs.com/package/@react-native-ohos/react-native-safe-area-context
[133] CPF-RN/rntpc_react-native-safe-area-context: https://atomgit.com/CPF-RN/rntpc_react-native-safe-area-context
[134] @react-native-ohos/clipboard: https://www.npmjs.com/package/@react-native-ohos/clipboard
[135] CPF-RN/rntpc_clipboard: https://atomgit.com/CPF-RN/rntpc_clipboard
[136] @react-native-ohos/react-native-nfc-manager: https://www.npmjs.com/package/@react-native-ohos/react-native-nfc-manager
[137] CPF-RN/rntpc_react-native-nfc-manager: https://atomgit.com/CPF-RN/rntpc_react-native-nfc-manager
[138] @react-native-ohos/jpush-react-native: https://www.npmjs.com/package/@react-native-ohos/jpush-react-native
[139] CPF-RN/rntpc_jpush-react-native: https://atomgit.com/CPF-RN/rntpc_jpush-react-native
[140] @react-native-ohos/react-native-default-preference: https://www.npmjs.com/package/@react-native-ohos/react-native-default-preference
[141] CPF-RN/rntpc_react-native-default-preference: https://atomgit.com/CPF-RN/rntpc_react-native-default-preference
[142] @react-native-ohos/react-native-smartrefreshlayout: https://www.npmjs.com/package/@react-native-ohos/react-native-smartrefreshlayout
[143] CPF-RN/rntpc_react-native-SmartRefreshLayout: https://atomgit.com/CPF-RN/rntpc_react-native-SmartRefreshLayout
[144] @react-native-ohos/react-native-date-picker: https://www.npmjs.com/package/@react-native-ohos/react-native-date-picker
[145] CPF-RN/rntpc_react-native-datepicker: https://atomgit.com/CPF-RN/rntpc_react-native-datepicker
[146] CPF-RN/usage-docs: https://atomgit.com/CPF-RN/usage-docs
[147] CPF-RN/ohos_react_native: https://atomgit.com/CPF-RN/ohos_react_native
[148] CPF-RN/skills: https://atomgit.com/CPF-RN/skills
本文由人人都是产品经理作者【nutpi】,微信公众号:【nutpi】,原创/授权 发布于人人都是产品经理,未经许可,禁止转载
题图来自Unsplash,基于 CC0 协议。
- 目前还没评论,等你发挥!

起点课堂会员权益



