本文记录把 react-native-button(经典按钮组件)适配到 HarmonyOS 的完整过程。

这个库极小:整个包只有 2 个 JS 文件(Button.js 150 行 + coalesceNonElementChildren.js 31 行),源码直发。但它有两个地方值得认真验:

① 它在非 iOS 上走的是 TouchableNativeFeedback

if (Platform.OS === 'ios') {
  return <TouchableOpacity … />;
} else {
  const background = this.props.androidBackground
    ? this.props.androidBackground
    : TouchableNativeFeedback.SelectableBackground();     // ← 无条件调用
  return (
    <View style={containerStyle}>
      <TouchableNativeFeedback … >
        <View style={{padding}}>{this._renderGroupedChildren()}</View>
      </TouchableNativeFeedback>
    </View>
  );
}

实测 Platform.OS === 'harmony' ⇒ 鸿蒙上走的就是 TouchableNativeFeedback 分支。
⇒ "这个按钮在鸿蒙上能不能点"就成了必须实测的问题(不是看文档能解决的)。

② 我在这里差点写下一个错误的结论

我第一次点击按钮时,日志里什么都没有 ⇒ 看起来像"鸿蒙上点不动"。
但我没有直接写这个结论,而是:

  1. 先核对点击坐标(从布局 dump 里取真实可点节点的中心,而不是自己按标记位置推算);
  2. 再建三个对照组 —— 直接用 TouchableOpacity / TouchableNativeFeedback / Pressable。

结果:

实例组件点击结果
B1库的 Button(启用)✅ 触发 onPress(并且 onPressIn / onPressOut 也触发)
B2库的 Button(disabled)✅ 不触发(源码门控生效)
C1直接用 TouchableOpacity✅ 触发
C2直接用 TouchableNativeFeedback✅ 触发
C3直接用 Pressable✅ 触发

⇒ 结论恰好相反:这个按钮在鸿蒙上工作正常。 我那次"没反应"是假阴性(点击坐标取自推算值、且中途还有一次漏了 force-stop 导致页面没切换)。

如果没有对照组和 dump 复核,我就会把"点了没反应"当成一个"鸿蒙适配问题"写进文章。

设备侧断言 28 / 28 全部通过(A 23 + B 3 + C 2)。

在这里插入图片描述


一、先说结论

项结果
上游最新版3.1.0;license: MIT;上游 star 767
库类型纯 JS 单组件库(class 组件):Button.js 150 行 + 一个 children 合并工具
是否需要原生适配不需要(无 harmony/、无 NativeModules)
运行时依赖⚠️⚠️ 两个:prop-types@^15.5.10(宿主已有)+ deprecated-react-native-prop-types@^3.0.1(宿主没有) ⇒ 目录/file: 接入会打包失败(本轮实测)
prepare 家族✅ 没有
mainButton.js(源码直发,交付包只有 2 个 JS 文件)
导出形态export default class Button ⇒ 默认导出是 class(typeof 'function'、prototype.render 存在)
需要 HAR / 权限 / ohpm❌ 都不需要
★ 鸿蒙上的渲染分支Platform.OS === 'harmony' ⇒ 非 iOS 分支 ⇒ View > TouchableNativeFeedback
★★ 可点性(实测)✅ 能点:onPress / onPressIn / onPressOut 都触发;disabled 时不触发
★ 像素判据启用文字 #007aff(蓝);disabled 文字 #dcdcdc(浅灰)⇒ 一对二值判据
★ 一个静默失效{...TouchableOpacity.propTypes} 在 RN 0.84 上贡献 0 个键(实测 propTypes 只有 9 个)
设备侧断言✅ 28 / 28 通过(A 23 + B 3 + C 2)

二、判定与接入

步做法结果
①package.json 里有没有 harmony.autolinking没有
②仓库里有没有 harmony/没有
③代码里有没有 NativeModules / requireNativeComponent全无
④import 图体检./coalesceNonElementChildren + prop-types + deprecated-react-native-prop-types + react / react-native ⇒ 两个真依赖都要查宿主
⑤scripts 扫 prepare 家族✅ 没有
npm install "git+https://atomgit.com/oh-react-native/react-native-button.git#3.1.0-ohos-1.0.0" --ignore-scripts

# ★★ 关键:两个运行时依赖,目录/软链接入都不会自动装
npm install prop-types --ignore-scripts
npm install deprecated-react-native-prop-types@^3.0.1 --ignore-scripts
// metro.config.js
watchFolders: [ path.resolve(__dirname, '../react-native-button') ],
import ButtonTestApp from './ButtonTestApp';
AppRegistry.registerComponent('ButtonTestApp', () => ButtonTestApp);
hdc shell aa force-stop com.rnoh084.demo
hdc shell aa start -b com.rnoh084.demo -a EntryAbility --ps rnAppKey ButtonTestApp

不需要 HAR、权限、ohpm、link-harmony。


三、读源码取到的真值(Button.js,150 行)

3.1 结构

import PropTypes from 'prop-types';
import { ViewPropTypes, TextPropTypes } from 'deprecated-react-native-prop-types';
import React, { Component } from 'react';
import { Platform, StyleSheet, Text, TouchableOpacity, TouchableNativeFeedback, View } from 'react-native';

export default class Button extends Component {
  static propTypes = {
    ...TouchableOpacity.propTypes,        // ★ 见 3.2
    accessibilityLabel: PropTypes.string,
    allowFontScaling: TextPropTypes.allowFontScaling,
    containerStyle: ViewPropTypes.style,
    disabledContainerStyle: ViewPropTypes.style,
    disabled: PropTypes.bool,
    style: TextPropTypes.style,
    styleDisabled: TextPropTypes.style,
    childGroupStyle: ViewPropTypes.style,
    androidBackground: PropTypes.object,
  };

3.2 ★ 一个静默失效:...TouchableOpacity.propTypes

实测 propTypes 键数 = 9,且键正好是上面那 9 个显式声明的:

propTypes 键 = accessibilityLabel, allowFontScaling, androidBackground, childGroupStyle,
               containerStyle, disabled, disabledContainerStyle, style, styleDisabled

⇒ TouchableOpacity.propTypes 在 RN 0.84 里已不存在(undefined),而 {...undefined} 在 JS 里是合法的(得空对象)⇒ spread 静默贡献 0 个键,不报错。

这条值得记住:老库常靠 ...SomeComponent.propTypes 继承校验;新 RN 把 propTypes 移除后,这行会静默失效——不报错、不警告,只是校验变少(也意味着这类"继承来的校验"在新 RN 上不能作为证据)。

3.3 ★★ 渲染分支(决定鸿蒙走哪条路)

render() {
  let touchableProps = { activeOpacity: this._computeActiveOpacity() };
  let containerStyle = [this.props.containerStyle,
                        this.props.disabled ? this.props.disabledContainerStyle : null];

  if (!this.props.disabled) {                    // ★ 门控:禁用时【根本不挂事件】
    touchableProps.onPress = this.props.onPress;
    touchableProps.onPressIn = this.props.onPressIn;
    touchableProps.onPressOut = this.props.onPressOut;
    touchableProps.onLongPress = this.props.onLongPress;
    touchableProps.delayPressIn = this.props.delayPressIn;
    touchableProps.delayPressOut = this.props.delayPressOut;
    touchableProps.delayLongPress = this.props.delayLongPress;
  }

  if (Platform.OS === 'ios') {
    return <TouchableOpacity …>{this._renderGroupedChildren()}</TouchableOpacity>;
  } else {
    const background = this.props.androidBackground
      ? this.props.androidBackground
      : TouchableNativeFeedback.SelectableBackground();
    let padding = 0;
    if (containerStyle[0] && containerStyle[0].padding) {   // ★ 布局小动作:把 padding 挪到内层
      padding = containerStyle[0].padding;
      containerStyle[0] = Object.assign({}, containerStyle[0], {padding: 0});
    }
    return (
      <View style={containerStyle}>
        <TouchableNativeFeedback {…touchableProps} background={background} …>
          <View style={{padding}}>{this._renderGroupedChildren()}</View>
        </TouchableNativeFeedback>
      </View>
    );
  }
}

实测:Platform.OS = harmony;TouchableNativeFeedback 在 RNOH 上是 function;TouchableNativeFeedback.SelectableBackground() 返回一个 object,不抛错 ✓
(Platform.constants 也拿到了:rnohArchitecture, reactNativeVersion, osFullName, deviceType, isTesting, Model。)

3.4 ★ 像素判据的根据

const styles = StyleSheet.create({
  text:         { color: '#007aff', fontSize: 17, fontWeight: '500', textAlign: 'center' },
  disabledText: { color: '#dcdcdc' },
  group:        { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center' },
});

_computeActiveOpacity() {
  if (this.props.disabled) { return 1; }
  return this.props.activeOpacity != null ? this.props.activeOpacity : systemButtonOpacity;   // 0.2
}
_renderGroupedChildren() {
  let style = [styles.text,
               disabled ? styles.disabledText : null,
               this.props.style,
               disabled ? this.props.styleDisabled : null];
  let children = coalesceNonElementChildren(this.props.children, (children, index) => (
    <Text key={index} style={style} …>{children}</Text>
  ));
  switch (children.length) {
    case 0:  return null;
    case 1:  return children[0];
    default: return <View style={childGroupStyle}>{children}</View>;
  }
}

⇒ 启用 ⇒ 文字蓝 #007aff;disabled ⇒ 文字浅灰 #dcdcdc ⇒ 同文案不同 disabled,颜色相反,可数像素 ✓


四、验证设计

判据内容
① 颜色二值对照同文案、只改 disabled ⇒ 蓝 vs 浅灰
② 点击行为启用应触发 onPress(+ onPressIn/onPressOut);disabled 应不触发
③ ★ 对照组同时直接用 TouchableOpacity / TouchableNativeFeedback / Pressable,用来排除"整页点不动"
④ 坐标必须来自 dump点位取真实可点节点的中心,不用推算值

五、实测结果

5.1 断言 28 / 28

组内容结果
A 契约default 是 class、prototype.render/_renderGroupedChildren/_computeActiveOpacity、propTypes 9 键、Platform.OS、TouchableNativeFeedback 与 SelectableBackground()、两个运行时依赖可加载、兼容包导出23/23
B 渲染与像素全部实例渲染未抛错、标题不与状态栏重合、像素判据设计3/3
C 交互与边界事件记录格式、点击次数记录、边界说明2/2
合计28/28

关键观测值:

default 导出的 typeof = function
propTypes 键数 = 9
propTypes 键 = accessibilityLabel, allowFontScaling, androidBackground, childGroupStyle,
               containerStyle, disabled, disabledContainerStyle, style, styleDisabled
★★ Platform.OS = harmony
Platform.constants = rnohArchitecture, reactNativeVersion, osFullName, deviceType, isTesting, Model
TouchableNativeFeedback 的 typeof = function
★ TouchableNativeFeedback.SelectableBackground() = function ⇒ object
prop-types 版本 = 15.8.1
deprecated-react-native-prop-types 版本 = 3.0.2
兼容包导出 = ColorPropType, EdgeInsetsPropType, ImagePropTypes, PointPropType,
             TextInputPropTypes, TextPropTypes, ViewPropTypes

5.2 ★ 颜色二值对照(像素)

实例配置蓝 #007aff灰 #dcdcdc
B1启用484925
B2disabled07633

⇒ 启用=蓝、禁用=灰,二值干净 ✓

在这里插入图片描述

5.3 ★★ 点击行为 + 对照组(本轮核心)

点位全部取自 dump 里真实 clickable 节点的中心:

[B1] 库的 Button(启用)     点 (660, 1635)  节点 y=1575..1695
     ⇒ PRESS onPress(启用按钮,第 1 次)    ★ 触发
     ⇒ IN onPressIn / OUT onPressOut        ★ 也触发
[B2] 库的 Button(disabled)  点 (660, 1978)  节点 y=1918..2038
     ⇒ (无新事件)                          ★ 不触发(门控生效)
[C1] 直接用 TouchableOpacity        点 (660, 916)  ⇒ PRESS C1 TouchableOpacity 对照组
[C2] 直接用 TouchableNativeFeedback 点 (660, 1338) ⇒ PRESS C2 TouchableNativeFeedback 对照组
[C3] 直接用 Pressable               点 (660, 1699) ⇒ PRESS C3 Pressable 对照组

事件记录里 6 条(截图可见):

IN onPressIn
OUT onPressOut
PRESS onPress(启用按钮,第 1 次)
PRESS C1 TouchableOpacity 对照组
PRESS C2 TouchableNativeFeedback 对照组
PRESS C3 Pressable 对照组

⇒ 结论:react-native-button 在鸿蒙上可正常点击,disabled 门控也正确;三个对照同时证明整页触摸链路正常,所以这个结论不是"整页点不动"造成的假象 ✓

在这里插入图片描述

在这里插入图片描述

5.4 UI:标题不与状态栏重合

TITLE measureInWindow y=420   (状态栏高 117)   ⇒ 420 > 117,不重合 ✓

六、★ 我差点写下的错误结论(本轮最值得记的一条)

过程:

  1. 我第一次点 B1(按"标记 y + 80"推算坐标),日志里什么都没有;
  2. 那一刻"鸿蒙上这个按钮点不动"是一个看起来很合理的结论 —— 因为源码里非 iOS 分支用的 TouchableNativeFeedback 在跨平台实现上确实可能不完整;
  3. 但我改成:先从 dump 取真实可点节点中心再点,并加了三个对照组;
  4. 重测后 B1 触发、B2 不触发、三个对照全触发 ⇒ 结论反转。

为什么会假阴性? 两个独立的流程错误叠在一起:

#错误后果
1点击坐标用推算值(标记 y + 偏移),没用 dump 里真实节点的中心可能落在节点外/被别的视图吃掉
2有一次启动漏了 aa force-stop,页面没切过去我点的是上一个库的测试页(dump 里发现标题是别的库)

⇒ 教训:涉及"点击没反应"这类否定性结论时,必须先满足两个前提再下判断 ——(a)点位来自 dump 的真实节点;(b)有对照组证明"整页是能点的"。 否定性结论比肯定性结论更需要证据。

这条和"先建对照组"是同一条纪律的两个方向:肯定性结论要防"假阳性"(比如动画没动却以为动了),否定性结论要防"假阴性"(点歪了却以为点不动)。


七、依赖坑:连续第二轮命中

deprecated-react-native-prop-types 不在宿主里,而 file: 接入不会自动装它 ⇒ 打包直接失败:

error Unable to resolve module deprecated-react-native-prop-types
from E:\rnoh-work\react-native-button\Button.js:
deprecated-react-native-prop-types could not be found within the project or in these directories:

装上 deprecated-react-native-prop-types@3.0.2 后立刻 exit 0 ✓
(它自己还带了 @react-native/normalize-color / invariant / prop-types,随之一起装上。)


八、我自己的其它失误(都在本轮被抓住)

#失误怎么发现的修法
1用动态 require:require(\${name}/package.json`)`Metro 报 Invalid call at line 151: require(...) —— Metro 要求 require 的实参可静态分析改成两条静态 require('xxx/package.json')
2按行号替换代码块时留下一个多余的 }npm run dev 报 Unexpected token, expected ","删掉多余括号
3打包失败却继续构建 HAP构建报了 BUILD SUCCESSFUL(用的是旧 bundle)⇒ 断言日志里根本没有本库的 tag分别检查两个退出码,并 grep 产物确认新页面在里面(见下)

第 3 条正是"打包与构建的退出码必须分别看"那个坑的复现:assembleHap 成功 ≠ 你测的是新代码。
本轮我用的确认手段:在 bundle.harmony.js 里 grep 页面名:

Select-String -Path harmony\entry\src\main\resources\rawfile\bundle.harmony.js -Pattern 'ButtonTestApp'
# 出现 8 次 ⇒ 新 bundle 确实在 HAP 里

九、已知限制与本次验证边界

9.1 用这个库要知道的

事项说明
必须手动装两个依赖prop-types + deprecated-react-native-prop-types(后者不装就打包失败)
...TouchableOpacity.propTypes 已静默失效RN 0.84 里 TouchableOpacity.propTypes 是 undefined ⇒ 实测 propTypes 只有 9 键
非 iOS 走 TouchableNativeFeedback鸿蒙上实测能点(onPress/onPressIn/onPressOut 均触发);但外观反馈(水波纹)来自 SelectableBackground(),视觉表现需自行确认
disabled 时事件根本不挂源码 if (!this.props.disabled) ⇒ 不给回调;activeOpacity 也变成 1
非 iOS 下 containerStyle.padding 会被挪到内层外层 padding 置 0、内层 <View style={{padding}}> 承接(净效果一致,但节点结构不同)
默认文字色 #007aff / 禁用 #dcdcdc通过 style / styleDisabled 覆盖
children 会被合并连续的非元素 children 会被合成一个 <Text>;多个元素则包一层 View(row)

9.2 本次验证的边界

  1. onLongPress / delayPressIn / delayPressOut / delayLongPress 未验证(只验了 onPress / onPressIn / onPressOut);
  2. androidBackground 自定义背景的视觉/行为未验证(B5 传了 Ripple,但 RNOH 无 Ripple 时我用 try/catch 兜成了 undefined ⇒ 该实例实际走的是 SelectableBackground() 分支);
  3. disabledContainerStyle / styleDisabled 未验证;
  4. allowFontScaling 未验证;
  5. 多 children 的 childGroupStyle 布局未验证(只渲染未断言);
  6. containerStyle.padding 挪位后的视觉等价性未逐像素比对;
  7. activeOpacity 的实际视觉反馈未验证(需要按下瞬间截图);
  8. 只在一台模拟器上验证(Pura X View,density 3,1320×2232),没有真机;未做跨平台对照。

未改动库代码。


十、常见问题

Q1:打包报 Unable to resolve module deprecated-react-native-prop-types?

它带的是真依赖,而目录/file: 接入不会安装目标包自己的 dependencies:

npm install deprecated-react-native-prop-types@^3.0.1 --ignore-scripts

(prop-types 也建议一起装上。)

Q2:这个按钮在鸿蒙上能点吗?

能。 实测:Platform.OS = harmony ⇒ 走非 iOS 分支(内部是 TouchableNativeFeedback),点击能触发 onPress / onPressIn / onPressOut;disabled 时不触发。
我同时用直接使用 TouchableOpacity / TouchableNativeFeedback / Pressable 的三个对照组排除了"整页点不动"的可能。

Q3:为什么 disabled 的按钮点了完全没反应?

这是设计如此:源码里只有 if (!this.props.disabled) 成立时才把 onPress/onPressIn/onPressOut/onLongPress 挂到 touchableProps 上;disabled 时事件根本不挂,并且 activeOpacity 变成 1(无反馈)。

Q4:怎么自定义样式?

<Button
  style={{color: '#D0021B', fontSize: 18}}          // 文字(启用)
  styleDisabled={{color: '#999999'}}                 // 文字(禁用)
  containerStyle={{padding: 12, backgroundColor: '#eef2f7'}}
  disabledContainerStyle={{opacity: 0.6}}
  childGroupStyle={{flexDirection: 'row'}}
  disabled={false}
  onPress={() => {}}
>确定</Button>

Q5:多个子元素会怎样?

连续的非元素 children 会被合并成一个 <Text>;如果有多个元素,会包一层 View(styles.group 是 flexDirection: 'row')。

Q6:activeOpacity 默认是多少?

disabled 时为 1;否则取 props.activeOpacity,未传则 0.2。

Q7:为什么 propTypes 比我预期的少?

因为它写了 ...TouchableOpacity.propTypes,而 RN 0.84 里 TouchableOpacity.propTypes 已不存在 ⇒ spread 得空对象、静默失效。实测只有 9 个键(源码里显式声明的那些)。

Q8:这个库需要鸿蒙侧做什么特殊处理吗?

不需要。 纯 JS、无原生模块、不需要 HAR / 权限 / ohpm。注意手动装两个依赖,其余按常规接入即可。


小结

react-native-button 是纯 JS 单组件库(2 个 JS 文件、源码直发)。设备侧 28 / 28 断言通过。

最值得记下来的是这几条:

  1. ★★ 否定性结论需要更多证据。 我第一次点击"没反应",看起来非常像"鸿蒙不支持 TouchableNativeFeedback";加上对照组(三个 touchable 直接用)并把点位改成 dump 里的真实节点中心之后,结论反转:按钮工作正常。
    ⇒ 凡是要下"点不动 / 收不到 / 不生效"这类否定判断,先满足两个前提:(a)点位/输入来自权威来源(dump);(b) 有对照组证明环境本身是好的。

  2. ★ 老库的 ...SomeComponent.propTypes 会静默失效。 RN 0.84 里 TouchableOpacity.propTypes 已是 undefined,{...undefined} 合法 ⇒ 不报错、只是校验变少(实测 propTypes 只有 9 键)。⇒ 这类"继承来的校验"在新 RN 上不能当作证据。

  3. ★ 依赖坑连续第二轮命中。 这次是 deprecated-react-native-prop-types(宿主没有)⇒ 打包 Unable to resolve module 直接 exit 1。⇒ 预检的 import 图体检 + 宿主依赖预查,两轮都提前给了信号。

  4. ★ 打包与构建的退出码必须分别看(坑 154 复现)。 我这轮 npm run dev 失败过,但 assembleHap 依然 BUILD SUCCESSFUL(装的是旧 bundle)。⇒ 判据:分别检查两个退出码,并在 bundle.harmony.js 里 grep 你的页面名确认新代码真的在产物里。

  5. ★ 页面切换要 force-stop 后再启动。 本轮有一轮实验点在了上一个库的测试页上(dump 里发现标题不对)。⇒ 每次实验前先 dump 一眼标题/标记,确认页面确实是目标页。


本篇用到的库

项内容
三方库react-native-button(上游 3.1.0 的鸿蒙适配版)
适配仓库https://atomgit.com/oh-react-native/react-native-button
适配 TAG3.1.0-ohos-1.0.0
需要 HAR / 权限 / ohpm都不需要(纯 JS)
库类型纯 JS 单组件库:跨平台按钮(class 组件,2 个 JS 文件)
运行时依赖⚠️ 两个:prop-types + deprecated-react-native-prop-types ⇒ 目录/file: 接入必须手动补装,否则打包失败
prepare / prepublish都没有
许可证MIT
上游仓库https://github.com/ide/react-native-button(★767)
宿主工程RNOH084Demo(测试页 rnAppKey = ButtonTestApp)
# 从适配仓库安装
npm install "git+https://atomgit.com/oh-react-native/react-native-button.git#3.1.0-ohos-1.0.0" --ignore-scripts

# 本地目录接入(开发常用)—— ★★ 两个依赖都要补
npm install ../react-native-button --ignore-scripts
npm install prop-types --ignore-scripts
npm install deprecated-react-native-prop-types@^3.0.1 --ignore-scripts
// metro.config.js
watchFolders: [ path.resolve(__dirname, '../react-native-button') ],
import Button from 'react-native-button';

// ① 基本用法
<Button
  style={{fontSize: 17, color: '#007aff'}}
  containerStyle={{padding: 10}}
  onPress={() => console.log('pressed')}
  onPressIn={() => {}}
  onPressOut={() => {}}
>
  确定
</Button>

// ② 禁用态(事件根本不会挂上)
<Button disabled styleDisabled={{color: '#dcdcdc'}} onPress={() => {}}>不可用</Button>

// ③ 自定义背景(非 iOS 平台;不传则用 SelectableBackground())
<Button androidBackground={/* 你的 background 对象 */} onPress={() => {}}>带背景</Button>

// ④ 多子元素会被包进一层 row 容器
<Button childGroupStyle={{flexDirection: 'row'}} onPress={() => {}}>
  <Text>左</Text>
  <Text>右</Text>
</Button>
# 换页启动测试页 —— ★ force-stop 不能省,否则可能仍在旧页面
hdc shell aa force-stop com.rnoh084.demo
hdc shell aa start -b com.rnoh084.demo -a EntryAbility --ps rnAppKey ButtonTestApp

判据的复现方式

# ① 颜色二值对照:启用文字 #007aff(蓝);disabled 文字 #dcdcdc(浅灰)
# ② 点击行为:点位必须取自 dump 里【真实 clickable 节点】的中心
#    注意 rnoh 的 dump 里可点节点只写 `clickable`(没有 =true)
devecocli ui layout | Select-String 'clickable'
# ③ 对照组:直接用 TouchableOpacity / TouchableNativeFeedback / Pressable 各一个,
#    用来排除"整页点不动";再用 dump 确认当前页面标题,避免点到上一个库的页面

# ④ 确认新 bundle 真的进了 HAP(防止"构建成功但装的是旧 bundle")
Select-String -Path harmony\entry\src\main\resources\rawfile\bundle.harmony.js -Pattern 'ButtonTestApp'

验证环境

项版本
React Native0.84.1
React19.2.3
RNOH(npm / ohpm)@react-native-oh/react-native-harmony / @rnoh/react-native-openharmony 0.84.3
Node.js / npmv24.14.0 / 11.9.0
DevEco Studio26.0.0.621
HarmonyOS SDKAPI 26(26.0.0.32)
设备HarmonyOS 7.0.0(26.0.0) Beta2 模拟器 Pura X View(ohos-x64),1320×2232,density 3
本机状态栏高度117px(页面留白取 48vp)
宿主依赖prop-types 15.8.1(已有)、deprecated-react-native-prop-types 3.0.2(初始不存在 ⇒ 打包失败 ⇒ 装后恢复)
宿主 HAP 产物entry-default-signed.hap
本次构建assembleHap 4 分 21 秒(最终一轮)
验证规模设备侧 28 / 28 断言;像素二值对照 2 例(蓝 4849/0、灰 25/7633);点击行为 5 例(库按钮启用/禁用 + 3 个对照);依赖坑 1 例(打包 exit 1 → 装依赖 → exit 0);UI 安全区 1 项

相关社区与项目地址

项目地址
React Native 鸿蒙官方社区(CPF-RN)https://atomgit.com/CPF-RN
RNOH 框架仓库https://atomgit.com/openharmony-RN/ohos_react_native
RNOH 三方库使用文档https://atomgit.com/OpenHarmony-RN/usage-docs
React Native for OpenHarmony 组织https://atomgit.com/oh-react-native
RN 三方库鸿蒙适配清单https://atomgit.com/oh-react-native/rn-ohos-adaptation-overview

欢迎加入 CPF-RN 鸿蒙社区:https://atomgit.com/CPF-RN

React Native for OpenHarmony 组织:https://atomgit.com/oh-react-native

RN 三方库鸿蒙适配清单:https://atomgit.com/oh-react-native/rn-ohos-adaptation-overview

Logo

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

更多推荐