众所周知 React Native 自 2021 年开始就宣布支持新的渲染器 Fabric 并开始逐渐迁移新架构 ,据 RN 开发团队的计划逐步迁移并在 2024 年底将会将新架构上线到 RN 正式版默认启用,并逐步放弃对旧架构的支持(当然段时间不会立即将旧架构部分移除,会在一定时间内保持兼容,就如同燃油车到电车的过程,那自然现在的阶段就会出现油电混动车)所以作为依赖库的维护者,我们现在开发和迁移自己的依赖就是最好的时机。


RN库代码

  • 在现行的 React Native 中,有很多属性是在 React 侧完成的封装,也有很多属性是平台独有的。为了达成这个效果,React Native 在 JS 侧根据 Platform 增加了很多判断。所以,React Native 的鸿蒙化适配也需要增加 OpenHarmony 相关的平台判断,与相应的组件属性的封装。为此,鸿蒙化团队提供了 react-native-harmony 的 tgz 包,并通过更改 metro.config.js 配置,将该 tgz 包应用到 Metro Bundler 中。
  • React Native 还提供了很多库的封装,例如 Codegen、打包工具等。为此,鸿蒙化团队提供了 react-native-harmony-cli 的包,对这些库进行了 OpenHarmony 平台的适配,用于向开发者提供相关的功能。

Fabric

Fabric 是 React Native 的组件渲染系统。接收 React Native 传过来的组件信息,处理后发送给 OS,由 OS 完成页面的渲染。

请添加图片描述

在适配方案中,组件不通过复杂的流程对接到 ArkUI 的声明式范式上,而是直接使用ContentSlot对接到 ArkUI 的后端接口进行渲染,缩短了流程,提高了组件渲染的效率。C-API 的性能收益包括以下的几个部分:

  • C 端最小化、无跨语言的组件创建和属性设置;
  • 无跨语言前的数据格式转换,不需要将 stringenum 等数据类型转换为 object,可以在 CPP 侧直接使用对应的数据进行处理;
  • 可以进行属性 Diff,避免重复设置,降低了属性设置的开销。

React Fabric是基于Fabric.js的React组件库,主要用于创建可交互的画布应用,支持图形绘制、手势操作和插件扩展等功能。

核心功能

  • 画布操作:支持矩形、文本等基础图形绘制,提供缩放、拖拽等交互功能 。 ‌
  • 插件系统:内置Pinch(触摸缩放)、FreeDraw(自由绘制)等插件,需额外安装依赖(如hammerjs) 。 ‌
  • 热区组件:可基于Fabric实现图片热区,支持链接绑定、样式切换和区域调整 。 ‌

安装与使用

安装命令:

npm install @cs-open/react-fabric
# 或
yarn add @cs-open/react-fabric

示例代码:

import { Canvas, Rect, Text } from '@cs-open/react-fabric';
function App() {
  return (
    <Canvas width={800} height={600}>
      <Rect left={100} top={100} width={200} height={100} fill="red" />
      <Text left={150} top={150} text="Hello Fabric!" fontSize={20} fill="white" />
    </Canvas>
  );
}

插件启用:

import { Pinch, FreeDraw } from '@cs-open/react-fabric/plugins';
<Canvas width={800} height={600}>
  <Pinch />
  <FreeDraw />
</Canvas>

通过下列代码可以对比出来新旧架构层在 Typescript(目前 Codegen 暂时仅支持 Flow 或 TypeScript 定义用于定义接口)的定义上区别

// 旧架构
import React from 'react';
import { requireNativeComponent, ViewStyle } from 'react-native';

const FeedAdComponent = requireNativeComponent('FeedAd');
export interface FeedAdProps {
    codeid: string;
    style?: ViewStyle;
    onAdError?: Function;
}

const TxFeedAd = (props: FeedAdProps) => {
    return (
        <FeedAdComponent
            codeid={props.codeid}
            style={props.style}
            onAdError={props.onAdError}
        />
    )
}

// 新架构
import type { ViewProps } from 'react-native';
import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';
import type {
  DirectEventHandler,
  Int32,
} from 'react-native/Libraries/Types/CodegenTypes'; // https://github.com/reactwg/react-native-new-architecture/discussions/27

export type AdFailWithErrorEventReply = Readonly<{
  code: Int32;
  message: string;
}>;

interface FeedViewProps extends ViewProps {
  codeId: string;
  onAdError?: DirectEventHandler<
    Readonly<AdFailWithErrorEventReply>
  >; 
}

export default codegenNativeComponent<FeedViewProps>('FeedView');

通过上面 react-native-ad 中 Feed 广告的重构部分代码摘录就能看出来,首先旧架构中 requireNativeComponent 获取到的原生对象其实是一个 any 类型的 Comment 所以在导出组件时,通常需要另外定义一个用于导出合理类型声明的函数组件套用。而新架构上的话 codegenNativeComponent 直接通过定义类型泛型能够直接导出指定 props 类型的 Comment 组件。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐