React Native快速上手OpenHarmony真机开发
一开始的困惑其实很简单:OpenHarmony 生态不熟,DevEco Studio 也不熟。如果一上来就写大量 ArkTS/原生代码,学习曲线会非常陡。所以我选择先从 React Native for OpenHarmony(RNOH) 入门,用自己更熟悉的 React 思维先把 UI 跑起来,再逐步理解鸿蒙侧的结构与原理。C:\Users\用户名\AppData\Local\Huawei\Sd
Day1:React Native for OpenHarmony(RNOH)新手:环境就绪 + 真机运行验证(含 React 学习结构)
作为刚开始接触 OpenHarmony、DevEco Studio 和 React 的初学者,Day1 给自己的目标是:按“Windows 11 + DevEco Studio + OpenHarmony SDK + React Native for OpenHarmony(RNOH)”这条常见流程,把链路完整跑通一次:创建工程 → 集成 RN → 真机运行 → 用最小 React 示例验证交互。
本篇你能收获什么(React 学习结构)
- 工程层面:把 RN 页面跑到 OpenHarmony 真机上
- React / RN 侧(通用能力)
- 组件渲染:函数组件 + JSX
- 状态更新:
useState - 副作用:
useEffect - 事件交互:
onPress等
- OpenHarmony / ArkTS 侧(平台能力)
- UIAbility / Entry / 页面入口(
EntryAbility.ets、Index.ets) - RN 容器:
RNApp、appKey、jsBundleProvider - 调试与排错:白屏、bundle、同步工程
- UIAbility / Entry / 页面入口(
一. 为什么选择从 React Native for OpenHarmony 开始
一开始的困惑其实很简单:OpenHarmony 生态不熟,DevEco Studio 也不熟。如果一上来就写大量 ArkTS/原生代码,学习曲线会非常陡。
所以我选择先从 React Native for OpenHarmony(RNOH) 入门,用自己更熟悉的 React 思维先把 UI 跑起来,再逐步理解鸿蒙侧的结构与原理。
二. 关键环境变量配置
2.1 配置 hdc 环境变量(Path)
- 右键“开始” → “系统” → “高级系统设置” → “环境变量”
- 在“系统变量”中找到
Path→ 编辑 → 添加 hdc 路径 - 重要:必须指向
toolchains目录,不是父目录
C:\Users\用户名\AppData\Local\Huawei\Sdk\default\openharmony\toolchains(默认安装在C盘)
2.2 配置 HDC_SERVER_PORT
变量名: HDC_SERVER_PORT
变量值: 7035
2.3 配置 CAPI 架构
变量名: RNOH_C_API_ARCH
变量值: 1
2.4 清理 npm 缓存(可选)
npm cache clean --force
三. 鸿蒙依赖安装与配置
3.1 添加 harmony 脚本到 package.json
{
"scripts": {
"harmony": "react-native bundle-harmony --dev"
}
}
3.2 安装鸿蒙化依赖包(注意版本匹配)

npm i @react-native-oh/react-native-harmony@0.72.90
四. 鸿蒙侧集成 RNOH
4.1 创建目录结构

4.2 CMakeLists.txt(关键片段)
project(rnapp)
cmake_minimum_required(VERSION 3.4.1)
set(CMAKE_SKIP_BUILD_RPATH TRUE)
set(OH_MODULE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules")
set(RNOH_APP_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
set(RNOH_CPP_DIR "${OH_MODULE_DIR}/@rnoh/react-native-openharmony/src/main/cpp")
set(RNOH_GENERATED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/generated")
set(CMAKE_ASM_FLAGS "-Wno-error=unused-command-line-argument -Qunused-arguments")
set(CMAKE_CXX_FLAGS "-fstack-protector-strong -Wl,-z,relro,-z,now,-z,noexecstack -s -fPIE -pie")
add_compile_definitions(WITH_HITRACE_SYSTRACE)
set(WITH_HITRACE_SYSTRACE 1)
add_subdirectory("${RNOH_CPP_DIR}" ./rn)
add_library(rnoh_app SHARED
"${RNOH_CPP_DIR}/RNOHAppNapiBridge.cpp"
"./PackageProvider.cpp"
)
target_link_libraries(rnoh_app PUBLIC rnoh)
4.3 PackageProvider.cpp(关键片段)
#include "RNOH/PackageProvider.h"
using namespace rnoh;
std::vector<std::shared_ptr<Package>> PackageProvider::getPackages(Package::Context ctx) {
return {};
}
4.4 修改 build-profile.json5(确保包含 x86_64 供模拟器用)
{
apiType: "stageMode",
buildOption: {
externalNativeOptions: {
path: "./src/main/cpp/CMakeLists.txt",
arguments: "",
cppFlags: "",
abiFilters: ["arm64-v8a", "x86_64"],
},
},
}
4.5 修改 EntryAbility.ets
import { RNAbility } from '@rnoh/react-native-openharmony';
export default class EntryAbility extends RNAbility {
protected getPagePath(): string {
return "pages/Index"
}
override onCreate(want: Want): void {
super.onCreate(want);
// 原有初始化代码...
}
}
4.6 创建 RNPackagesFactory.ets
import { RNPackageContext, RNPackage } from '@rnoh/react-native-openharmony/ts';
export function createRNPackages(ctx: RNPackageContext): RNPackage[] {
return [];
}
4.7 Index.ets(关键配置)
import {
AnyJSBundleProvider,
ComponentBuilderContext,
FileJSBundleProvider,
MetroJSBundleProvider,
ResourceJSBundleProvider,
RNApp,
RNOHErrorDialog,
RNOHLogger,
TraceJSBundleProviderDecorator,
RNOHCoreContext
} from '@rnoh/react-native-openharmony';
import { createRNPackages } from '../RNPackagesFactory';
@Builder
export function buildCustomRNComponent(ctx: ComponentBuilderContext) {}
const wrappedCustomRNComponentBuilder = wrapBuilder(buildCustomRNComponent)
@Entry
@Component
struct Index {
@StorageLink('RNOHCoreContext') private rnohCoreContext: RNOHCoreContext | undefined = undefined
@State shouldShow: boolean = false
private logger!: RNOHLogger
aboutToAppear() {
this.logger = this.rnohCoreContext!.logger.clone("Index")
const stopTracing = this.logger.clone("aboutToAppear").startTracing();
this.shouldShow = true
stopTracing();
}
onBackPress(): boolean | undefined {
// Ark 侧默认 back 会终止/后台,交给 RN 处理
this.rnohCoreContext!.dispatchBackPress()
return true
}
build() {
Column() {
if (this.rnohCoreContext && this.shouldShow) {
if (this.rnohCoreContext?.isDebugModeEnabled) {
RNOHErrorDialog({ ctx: this.rnohCoreContext })
}
RNApp({
rnInstanceConfig: {
createRNPackages,
enableNDKTextMeasuring: true,
enableBackgroundExecutor: false,
enableCAPIArchitecture: true,
arkTsComponentNames: []
},
initialProps: { "foo": "bar" } as Record<string, string>,
appKey: "Test0121",
wrappedCustomRNComponentBuilder: wrappedCustomRNComponentBuilder,
onSetUp: (rnInstance) => {
rnInstance.enableFeatureFlag("ENABLE_RN_INSTANCE_CLEAN_UP")
},
jsBundleProvider: new TraceJSBundleProviderDecorator(
new AnyJSBundleProvider([
new MetroJSBundleProvider(),
new FileJSBundleProvider('/data/storage/el2/base/files/bundle.harmony.js'),
new ResourceJSBundleProvider(this.rnohCoreContext.uiAbilityContext.resourceManager, 'hermes_bundle.hbc'),
new ResourceJSBundleProvider(this.rnohCoreContext.uiAbilityContext.resourceManager, 'bundle.harmony.js')
]),
this.rnohCoreContext.logger),
})
}
}
.height('100%')
.width('100%')
}
}
-
appKey必须与 React Native 工程中AppRegistry.registerComponent注册的名称完全一致,否则会导致白屏。 -
enableNDKTextMeasuring和enableCAPIArchitecture必须设置为true,否则应用无法正常启动。 -
每次修改 CPP 侧代码后,必须点击 DevEco Studio 右上角的 Sync Now 同步工程。
五. 运行结果截图
已经在鸿蒙设备上看到 React Native 页面成功启动。
后续发布到 CSDN 时,会在这里补充:设备型号 / OpenHarmony 版本 / DevEco 版本 / RNOH 版本。

六. 常见问题与排查
- 现象:白屏
- 可能原因:
appKey不一致 - 如何验证:对照
AppRegistry.registerComponent('xxx')的名字 - 解决:保持两边完全一致
- 可能原因:
- 现象:修改 C++ 后无变化
- 可能原因:未同步工程
- 解决:点击 Sync Now 再构建
- 现象:找不到 bundle / Metro 不生效
- 可能原因:
jsBundleProvider选择了 File/Resource,但文件不存在 - 解决:先用
MetroJSBundleProvider()跑通,再逐步切到 file/resource
- 可能原因:
七. 环境清单
- Windows:Windows 11
- DevEco Studio:
- OpenHarmony SDK:
- React Native:
- RNOH:@react-native-oh/react-native-harmony@0.72.90
欢迎加入开源鸿蒙跨平台社区: https://openharmonycrossplatform.csdn.net
更多推荐


所有评论(0)