1. 项目概述:为什么在 OpenHarmony 上要自己封装确认弹窗
做跨端开发这几年,我在很多项目里都得手写确认取消弹窗。这套东西看着简单,真正落到 OpenHarmony 设备上时,坑一点也不少。前段时间项目的任务标题就叫“React Native + OpenHarmony:Modal确认取消弹窗”,实际做完后我发现,这不只是写一个 <Modal> 标签的事,还牵扯到 RN 在鸿蒙环境里的启动流程、设备选型、样式适配和交互状态管理。这篇文章就围绕这个需求,把我从工程搭建到弹窗封装、真机调试、踩坑修复的完整过程写出来,给正在做同类事情的同学一份可以直接抄的参考。
“确认取消弹窗”这个需求,本质上是产品交互里的一个“二次确认”机制。用户点击“删除”“提交”“退出”这类破坏性操作或不可逆操作时,界面不能直接执行,而要弹出一个对话框,让用户再思考一次。React Native 官方提供了 Modal 组件,但 Modal 只是一个承载层,确认取消按钮、标题、说明文字、遮罩颜色、点击遮罩是否关闭,都需要自己用 View 和 Pressable 组合出来。这个项目的核心,不是把系统 Alert 调出来,而是用 RN 的 Modal 能力,在 OpenHarmony 上实现一套可控、可复用、视觉统一的确认弹窗组件。
你如果去搜“React Native + OpenHarmony”,会看到两类信息:一类是 React Native for OpenHarmony 的安装和移植教程,另一类就是各种设备相关的坑,比如“openharmony的rk3568有许多设备树到底咋选”“openharmony rk3588”这类。这说明目前想在这套环境里做事,最大的成本往往不是 JS 业务逻辑,而是“工程能不能顺利跑起来”。Modal 这种业务层组件,其实已经算后话了;但在你能看到一个弹窗之前,需要先解决宿主环境、构建工具、真机调试这些更底层的问题。所以这篇虽然标题是“Modal 确认取消弹窗”,我也花了不少篇幅在环境与排查上,这部分绕不开。
如果你是以下几种情况,这篇会比较有用:第一,手上有一个基于 React Native 的存量应用,正打算往 OpenHarmony 设备上迁移,想知道 Modal 这些基础组件能不能直接用;第二,你正在 OpenHarmony 开发板上做新项目,界面用 RN 写,需要一个不被系统风格绑架的自定义确认弹窗;第三,你已经把页面跑起来了,但发现弹窗显示异常、点击失效、遮罩不透明,想看有没有现成的排查套路。基础要求是:你至少会 JS/TS,且对 React Native 组件模型有一定了解;不需要你先懂 ArkUI,因为弹窗这一层完全可以在 RN 侧完成。
1.1 这个项目到底解决什么问题
我这次要做的功能,业务上非常简单:列表页里有一条记录,用户点击“删除”按钮后,不能立刻删,要先弹一个对话框,上面写“确定要删除这条记录吗?”,下面两个按钮,左边“取消”,右边“删除”。用户点“删除”,数据才真的清掉,同时接口请求、页面刷新、日志上报这些后续动作才触发。
这种弹窗如果放在 Android 原生里,用 AlertDialog 就能做;放在 iOS 原生里,用 UIAlertController 也能做。但到了 React Native 这一层,问题就变了:RN 里的是跨平台抽象组件,它最终要映射到宿主平台上。OpenHarmony 本身有自己的弹窗能力,比如 ArkUI 的 AlertDialog、CustomDialog,但 React Native for OpenHarmony 这个移植方案,能不能把 RN 的 Modal 一对一映射好,是需要验证的。我在做之前翻了不少 issue,确实有一些版本里 Modal 的透明背景、动画效果、返回键处理并不完全跟 Android 一致。
所以这个项目的真正难点不是“弹窗怎么写”,而是“在 OpenHarmony 上用 RN 写弹窗,怎么保证行为和视觉都可控”。我最后选择了完全自定义,不用系统 Alert,把所有样式和交互都放进一个 ConfirmDialog 组件里。这样即便底层 Modal 在某些细微行为上有差异,我也能通过参数约束住,不会让用户在不同的设备上看到完全不一样的确认框。
1.2 从热搜词看 RN + OpenHarmony 的生态现状
我顺手看了一眼和标题相关的最新网络热词,发现一个很有意思的现象:排在前面的大量内容是“react native 启动白屏”“openharmony的rk3568有许多设备树到底咋选”“openharmony rk3568”“openharmony rk3588”“openharmony usbmanager libusb的使用”这类底层和接入问题。真正聊业务组件、聊弹窗设计的反而少。这其实间接说明,React Native for OpenHarmony 目前对很多人来说,还处在“能把应用跑起来”的阶段,离“像写 Android/iOS 那样舒服地写业务”还有一段路。
“启动白屏”这个关键词,基本是每个迁到 OpenHarmony 的 RN 开发者都会撞上的问题。很多时候不是你的代码有问题,而是 Metro bundle 没加载出来,或者 OpenHarmony 原生侧还没把 JS 入口执行起来。你连白屏都看不到,自然更不可能看到 Modal 弹窗。另一些热词集中在 rk3568、rk3588、设备树、USB 驱动上,这些是开发板适配层面的问题。我的看法是:如果你只是做应用开发,设备树可以理解为“系统内核和硬件之间的说明书”,它不属于业务开发的工作范围;但如果你不得不自己编译 OpenHarmony 系统镜像,那你得搞清楚开发板型号、内核版本和 dts/dtsi 之间的关系,否则后续调试会很痛苦。文章后面我会用一小节专门讲这个。
1.3 适合谁来参考
我写这篇内容时,默认读者已经对 React Native 的基础语法有了解,比如组件、Props、State 这些都不需要额外解释。但我不默认你懂 OpenHarmony 的设备移植。因为很多人其实是半路接了一个“把 RN 应用跑在 OpenHarmony 开发板上”的任务,对鸿蒙侧完全是陌生的。
如果你是下面这几种人,这篇内容可以直接读:
- 你正在把 RN 应用往 OpenHarmony 设备上迁移,卡在启动白屏或者弹窗显示异常。
- 你想自己封装一个通用确认弹窗,而不是到处写重复的
<Modal>代码。 - 你需要知道 Modal 的几个关键属性能不能在 OpenHarmony 上正常工作,以及出了问题怎么排查。
- 你用的是 rk3568 或 rk3588 这类开发板,搞不清设备树和你的应用有什么关系。
那接下来,我先从环境准备开始讲。因为 Modal 显示不出来这件事,十次里有八次不是 Modal 本身的问题,是工程根本没跑起来。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 环境准备:把 React Native 工程跑到 OpenHarmony 设备上
Modal 组件的代码写起来并不长,但我在没有把环境跑通之前,根本看不到任何弹窗效果。所以这一节先解决“让 RN 应用在 OpenHarmony 上正常显示”这件事。这块坑非常多,我尽量把顺序捋清楚。
2.1 依赖安装与工程初始化
如果你是从一个现成的 React Native 工程开始,第一步不是先写弹窗,而是先确认 OpenHarmony 侧能不能加载你的 JS bundle。目前社区对 OpenHarmony 的 React Native 适配,普遍叫 RNOH,也就是 React Native for OpenHarmony。做法通常是在 OpenHarmony 工程里引入 RNOH 的 SDK,再在 JS 侧把 react-native 换成适配版本。安装的时候不建议盲从网上的旧教程,直接到 React Native for OpenHarmony 相关的官方组织或仓库看当前版本,package.json 里的包名一般形如 `@react-native-oh-tpl/rea
