一个基于华为鸿蒙操作系统(OpenHarmony)与 React Native 深度集成的酒店页面组件实现。这段代码展示了在现代跨平台移动应用开发中,如何将原生鸿蒙组件与React Native的JavaScript逻辑进行无缝衔接,构建高性能的混合架构应用。

从技术架构的宏观层面分析,这段代码构建了一个完整的酒店业务模块,采用了鸿蒙应用开发的声明式UI范式与React Native的组件化思想相结合的设计理念。代码结构清晰地分为导入依赖、组件装饰、状态管理、生命周期函数和UI构建等多个逻辑层次。

在导入部分,代码引入了多个关键模块:RNApp 是React Native在鸿蒙平台上的主应用容器组件;RNOHErrorDialog 负责显示错误对话框;RNOHLogger 提供日志记录功能;RNOHCoreContext 是核心上下文对象;RNInstance 代表React Native实例;ResourceJSBundleProvider 负责JavaScript bundle资源的加载和管理。这些模块共同构成了React Native在鸿蒙平台上运行的基础环境。

RNInstanceManager 是自定义的React Native实例管理器,负责协调多个React Native实例的生命周期。buildCustomRNComponent 和 wrapBuilder 函数用于构建和包装自定义的React Native组件,这种设计模式体现了高阶组件(HOC)的编程思想。

@Entry 装饰器标识这个组件是一个页面入口,这是鸿蒙应用开发的标准规范。@Component 装饰器声明这是一个自定义组件结构。组件命名为 Hotel,明确标识了其业务领域归属。

在状态管理方面,代码使用了鸿蒙的响应式状态系统。@StorageLink(‘RNOHCoreContext’) 装饰器创建了一个与AppStorage双向绑定的rnohCoreContext属性,这种机制确保了应用状态的全局一致性管理。


说明

这是一个多jsBundle和多rnInstance的demo工程。

目录结构

MutilBundleSample
├── FlightRN 机票前端工程
├── HotelRN 酒店前端工程
├── NativeProject 鸿蒙工程
└── README.md

环境搭建

  1. FlightRN 中运行 npm i @react-native-oh/react-native-harmony@x.x.xyarn add @react-native-oh/react-native-harmony@x.x.x 安装依赖,运行 npm run dev:all 生成机票的jsBundle;
  2. HotelRN 中运行 npm i @react-native-oh/react-native-harmony@x.x.xyarn add @react-native-oh/react-native-harmony@x.x.x 安装依赖,运行 npm run dev:all 生成酒店的jsBundle;
  3. entry 目录下执行 ohpm i @rnoh/react-native-openharmony@x.x.x 安装依赖;
  4. 检查 NativeProjectentry 目录下是否生成 oh-modules 文件夹;
  5. 用 DevEco Studio 打开 NativeProject,执行 Sync and Refresh Project
  6. 点击 File > Project Structure > Signing Configs,登录并完成签名;
  7. 点击右上角的 run 启动项目。

效果预览

启动后页面效果如下:

请添加图片描述
@Entry 装饰器标识这个组件是一个页面入口,这是鸿蒙应用开发的标准规范。@Component 装饰器声明这是一个自定义组件结构。组件命名为 Hotel,明确标识了其业务领域归属。

在状态管理方面,代码使用了鸿蒙的响应式状态系统。@StorageLink(‘RNOHCoreContext’) 装饰器创建了一个与AppStorage双向绑定的rnohCoreContext属性,这种机制确保了应用状态的全局一致性管理。

@State shouldShow: boolean = false 定义了一个组件内部的状态变量,用于控制UI的显示逻辑。这种状态分离的设计使得组件的渲染逻辑更加清晰可控。

aboutToAppear 是一个异步生命周期函数,在组件即将显示时执行。函数内部首先通过this.rnohCoreContext!.logger.clone(“Hotel”) 创建了一个专用的日志记录器实例,这种设计便于在复杂应用中追踪特定模块的运行状态。

使用logger.startTracing() 和 stopTracing() 方法(注意:代码中可能存在拼写错误,应为stopTracing)来记录性能追踪信息,这对于优化应用启动性能具有重要意义。

通过RNInstanceManager.getInstance(“Hotel”) 异步获取之前准备好的React Native实例。这个实例的获取过程体现了资源预加载的设计思想,通过提前准备React Native运行环境来减少用户等待时间。

在获取到rnInstance后,将shouldShow状态设置为true,触发UI的重新渲染。这种条件渲染模式在复杂应用中非常常见,可以避免在资源未准备好时显示不完整的界面。

import router from '@ohos.router';
import { ResourceJSBundleProvider, } from '@rnoh/react-native-openharmony';
import { RNInstanceManager } from "../rn/RNInstanceManager";

@Entry
@Component
struct Index {
  aboutToAppear() {
    RNInstanceManager.prepareRN('Hotel', new ResourceJSBundleProvider(
      getContext().resourceManager, 'bundle/basic/basic.harmony.bundle'))
    RNInstanceManager.prepareRN('Flight', new ResourceJSBundleProvider(
      getContext().resourceManager, 'bundle/basic/basic.harmony.bundle'))
  }

  build() {
    Column() {
      Button("前往酒店页面")
        .margin({
          bottom: 50
        })
        .onClick(() => {
          router.pushUrl({
            url: 'pages/Hotel'
          })
        })

      Button("前往机票页面")
        .onClick(() => {
          router.pushUrl({
            url: 'pages/Flight'
          })
        })
    }
    .justifyContent(FlexAlign.Center)
    .width('100%')
    .height('100%')
    .alignItems(HorizontalAlign.Center)
  }
}
import {
  RNApp,
  RNOHErrorDialog,
  RNOHLogger,
  RNOHCoreContext,
  RNInstance,
  ResourceJSBundleProvider
} from '@rnoh/react-native-openharmony';
import { RNInstanceManager } from "../rn/RNInstanceManager";
import { buildCustomRNComponent } from "../rn/CustomRNComponent";

const wrappedCustomRNComponentBuilder = wrapBuilder(buildCustomRNComponent);

@Entry
@Component
struct Hotel {
  @StorageLink('RNOHCoreContext') private rnohCoreContext: RNOHCoreContext | undefined = undefined;
  @State shouldShow: boolean = false;
  private logger!: RNOHLogger;
  private rnInstance: RNInstance | undefined;

  async aboutToAppear() {
    this.logger = this.rnohCoreContext!.logger.clone("Hotel");
    const stopTracing = this.logger.clone("aboutToAppear").startTracing();
    this.rnInstance = await RNInstanceManager.getInstance("Hotel");
    this.shouldShow = true;
    stopTracing();
  }

  onBackPress(): boolean | undefined {
    this.rnohCoreContext!.dispatchBackPress();
    return true;
  }

  build() {
    Column() {
      if (this.rnohCoreContext && this.shouldShow) {
        if (this.rnohCoreContext?.isDebugModeEnabled) {
          RNOHErrorDialog({ ctx: this.rnohCoreContext });
        }
        RNApp({
          rnInstanceConfig: {
            rnInstance: this.rnInstance as RNInstance,
          },
          initialProps: { "foo": "bar" } as Record<string, string>,
          appKey: "hotel",
          wrappedCustomRNComponentBuilder: wrappedCustomRNComponentBuilder,
          onSetUp: (rnInstance) => {
            rnInstance.enableFeatureFlag("ENABLE_RN_INSTANCE_CLEAN_UP")
          },
          jsBundleProvider: new ResourceJSBundleProvider(
            this.rnohCoreContext.uiAbilityContext.resourceManager, 'bundle/cp/hotel.harmony.bundle')
        })
      }
    }
    .height('100%')
    .width('100%')
  }
}

onBackPress 函数处理设备的返回按钮事件。当用户按下返回键时,函数会通过this.rnohCoreContext!.dispatchBackPress() 分发返回事件,然后返回true表示事件已被处理,这种机制确保了导航栈的正确管理。

build 方法是组件的核心,定义了UI的层次结构和渲染逻辑。使用Column容器创建垂直布局,通过条件判断 this.rnohCoreContext && this.shouldShow 来决定是否显示主要内容。这种防御性编程模式避免了在上下文环境未准备好时的运行时错误。

在条件满足时,首先检查是否启用了调试模式,如果this.rnohCoreContext?.isDebugModeEnabled为真,则显示RNOHErrorDialog组件,为开发者提供错误诊断界面。

RNApp 组件是整个React Native内容的承载容器。rnInstanceConfig 配置对象包含rnInstance属性,指定要使用的React Native实例。initialProps 设置了初始属性 { “foo”: “bar” },这是一个示例性的配置,在实际业务中会被替换为真实的业务数据。

appKey: “hotel” 为这个React Native应用指定了唯一的标识符,这对于多实例管理至关重要。wrappedCustomRNComponentBuilder 参数传递了包装后的自定义组件构建器,这种设计模式支持组件的动态扩展和定制。

jsBundleProvider 使用ResourceJSBundleProvider来加载特定的JavaScript bundle文件。这里指定的路径是 ‘bundle/cp/hotel.harmony.bundle’,这表明酒店模块拥有自己独立的业务逻辑代码。

ResourceJSBundleProvider 的构造函数接受两个参数:this.rnohCoreContext.uiAbilityContext.resourceManager 提供资源管理能力,确保bundle文件能够正确加载和解析。

样式设置方面,Column容器通过.height(‘100%’) 和 .width(‘100%’) 设置为充满整个屏幕空间,这确保了应用在不同尺寸设备上的一致性表现。

从工程实践的角度深入分析,这段代码体现了多个重要的软件设计原则:首先是单一职责原则,Hotel组件专注于酒店业务逻辑的实现;其次是依赖倒置原则,通过接口和抽象来管理模块间的依赖关系;第三是开闭原则,通过组件化的设计支持功能扩展。

在性能优化方面,代码采用了异步加载、资源预准备、条件渲染等多种技术手段。这种综合性的优化策略确保了应用在保持功能丰富性的同时,仍然能够提供流畅的用户体验。

从业务架构的角度,这个酒店页面组件是一个典型的垂直业务模块实现。它封装了酒店预订、搜索、详情展示等相关的所有业务逻辑。

错误处理机制也值得关注。通过RNOHErrorDialog组件,应用能够在调试模式下提供详细的错误信息,这对于开发阶段的问题诊断和修复具有重要价值。

日志系统的设计体现了企业级应用开发的成熟度。通过可配置的日志级别、追踪功能和分类管理,开发者可以全面掌握应用的运行状态。

在鸿蒙生态系统的大背景下,这段代码代表了原生平台与跨平台技术栈融合的最新发展趋势。通过这种深度集成方案,应用既能够享受React Native开发效率的优势,又能够获得鸿蒙原生平台的性能表现。

代码中使用的装饰器语法是鸿蒙应用开发的特色之一。@Entry、@Component、@StorageLink、@State 等装饰器共同构成了声明式UI编程的基础。
请添加图片描述

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐