RN-Native Integration

Below we use the accompanying MyApplicationReplace replacement files and SampleApp project to illustrate three common scenarios you may encounter when using RNApp, RNSurface, RNInstance. This section describes the specific steps for three scenarios.

Configuration Required for Using React Native

  1. rnInstanceConfig: RNInstance or RNInstanceOptions for creating RNInstance. If RNInstanceOptions is provided, this component is responsible for creating and managing RNInstance.

  2. To ensure React Native Harmony effects match iOS or Android, configure the following switches in module.json5 in the project entry directory:

    • half_leading: After setting lineHeight attribute, the default font engine layout doesn't center by line height. Enable this switch for text centering;
    • can_preview_text: Currently TextInput cannot display Chinese pinyin when typing. Enable this switch to display pinyin.
      // module.json5
      "metadata": [
        {
          "name": "half_leading",
          "value": "true"
        },
        {
          "name": "can_preview_text",
          "value": "true"
        }
      ]
      
  3. To use bundles or images from sandbox paths, refer to How to Load Sandbox Path Bundle and Images.

Single Instance, Single Surface, Single Bundle

This scenario is the simplest in RN Native projects. You can directly use RNApp for page construction. Based on your business scenario, you can also split RNApp into RNSurface and RNInstance for flexible use. For detailed process of creating RNSurface and RNInstance, refer to source code @rnoh/react-native-openharmony/src/main/ets/RNApp.ets.

Steps to use RNApp directly:

  1. Modify EntryAbility class to inherit from RNAbility class, specifying entry page path.

    // MyApplicationReplace/entry/src/main/ets/entryability/EntryAbility.ets
    
    import { RNAbility } from '@rnoh/react-native-openharmony';
    
    export default class EntryAbility extends RNAbility {
      getPagePath() {
        return 'pages/Index';
      }
    }
    

    If inheriting and overriding RNAbility methods, you need to call super() method to ensure RNAbility logic is correct.

  2. In the entry file Index.ets, use RNApp.

    // MyApplicationReplace/entry/src/main/ets/pages/Index.ets
    
    import {
       AnyJSBundleProvider,
       ComponentBuilderContext,
       FileJSBundleProvider,
       MetroJSBundleProvider,
       ResourceJSBundleProvider,
       RNApp,
       RNOHErrorDialog,
       RNOHLogger,
       TraceJSBundleProviderDecorator,
       RNOHCoreContext
     } from '@rnoh/react-native-openharmony';
     import font from '@ohos.font';
     import { createRNPackages } from '../RNPackagesFactory';
    
     const arkTsComponentNames: Array<string> = [SampleView.NAME, GeneratedSampleView.NAME, PropsDisplayer.NAME];
     @Builder
     export function buildCustomRNComponent(ctx: ComponentBuilderContext) {
       Stack(){
       }
       .position({x:0, y: 0})
     }
    
     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()
         for (const customFont of fonts) {
           font.registerFont(customFont)
         }
    
         this.shouldShow = true
         stopTracing()
       }
       ...
     }