本文记录把 react-native-tag-input(标签输入框)适配到 HarmonyOS 的完整过程。

它做的事:把一组标签(tag)横向排列,末尾跟一个 TextInput 用于输入;
每个标签带一个 × 可点删除,Backspace 键在输入框为空时删掉最后一个标签。

结论:可用,而且是零 FAIL —— 23 条判据全 PASS。

这个库是我遇到的**“预检三个风险点、但每个都能提前判定为安全”**的典型:
它用了 ViewPropTypes.style 和 Text.propTypes.style(RN 0.44+ 已移除)、
写了 invariant(Platform.OS === 'ios', …)、还 import 了 RN 内部路径。
但逐条读上下文之后,这三个都能在动手之前判定为"不会出问题" ——
本文第一节就是这三条判定过程。

★★★★★ 一、三个风险点,逐条读上下文都判定为安全

预检扫描出三个会让人"心里一沉"的命中。但每一条读完上下文都排除了:

① ViewPropTypes.style / Text.propTypes.style(各 2 处)—— 需要 polyfill

// index.js L117-L118
tagContainerStyle: ViewPropTypes.style,
tagTextStyle: Text.propTypes.style,

(L380-L381 在 Tag 组件里同样有两处。)

判定:ViewPropTypes 与 Text.propTypes 在 RN 0.44+ 已被移除,
但工程里已经有一份 polyfill(polyfills/text-prop-types.js,在 index.js 第 28 行导入),
它同时补了 ViewPropTypes(Object.defineProperty getter 形式)与 Text.propTypes。
⇒ 不需要新增任何东西,直接复用 ✓

实测结果:页面正常渲染、LogBox 无通知 ✓(后面第三节有证据)

② invariant(Platform.OS === "ios", …) —— 永远不会被执行

// index.js L209-L212
onBlur = (event) => {
  invariant(Platform.OS === "ios", "only iOS gets text on TextInput.onBlur");
  this.props.onChangeText(event.nativeEvent.text);
}

第一眼:鸿蒙上 Platform.OS !== 'ios' ⇒ invariant 会抛错 ⇒ 崩。

但看它的用法(L295):

onBlur={Platform.OS === "ios" ? this.onBlur : undefined}

⇒ ⇒ 鸿蒙上 Platform.OS !== 'ios',所以传给 TextInput 的是 undefined
⇒ ⇒ this.onBlur 永远不会被调用 ⇒ invariant 永远不会执行 ✓✓

判断要点:"代码里有 invariant(x)“不等于"它会执行” ——
要先看包含这个 invariant 的函数,在什么条件下才会被调用。
这里是同一个文件里两行的互相配合(L295 做了平台判断,L209 的 invariant 是对"这个 prop 只该在 iOS 传"的断言)。

③ import type { StyleObj } from 'react-native/Libraries/StyleSheet/StyleSheetTypes' —— 会被 Babel 消除

// index.js L1-L6
// @flow
import type {
  StyleObj,
} from 'react-native/Libraries/StyleSheet/StyleSheetTypes';

第一眼:这是 RN 的内部路径,Metro 很可能解析失败。

但它是 import type —— Flow 的类型导入,在转译时会被整体消除(不产生任何 require)。
⇒ Metro 根本看不到这条路径 ✓✓

实测结果:打包 bundle exit=0、构建 BUILD SUCCESSFUL ✓(后面第四节有记录)

三条判定的共同点

风险点表面现象实际
ViewPropTypes / Text.propTypes老 API,已移除有现成 polyfill
invariant(Platform.OS === 'ios')鸿蒙上会抛错该函数永不调用(调用处做了平台判断)
react-native/Libraries/... 内部路径Metro 会解析失败import type ⇒ 转译时消除

⇒ ⇒ 这类"预检命中"要先读上下文再决定要不要改代码 ——
如果一看到 ViewPropTypes 就动手改库,反而会引入不必要的改动。
本库代码最终零改动。

★★★★★ 二、23 条判据全 PASS —— SUMMARY | 合计 23/23 通过,失败 0

契约(17 条)

PASS | ★★★ TagInput 是 class(function)
PASS | ★★★ 有 prototype.render(它是 class 组件)
NOTE | TagInput.prototype.isPureReactComponent = true
PASS | ★★★★ 它是 PureComponent(isPureReactComponent === true)
PASS | ★★★★★ propTypes 清单(16 项)
PASS | ★★★★★ defaultProps 清单(6 项)
PASS | ★★★ defaultProps.editable = true
PASS | ★★★ defaultProps.tagColor = '#dddddd'
PASS | ★★★ defaultProps.tagTextColor = '#777777'
PASS | ★★★ defaultProps.inputDefaultWidth = 90
PASS | ★★★ defaultProps.inputColor = '#777777'
PASS | ★★★ defaultProps.maxHeight = 75
PASS | ★★★ 3 个方法在 prototype 上(render / cWRP / cWU)
PASS | ★★★★ 箭头类字段【不在】prototype 上(focus/removeIndex/scrollToEnd/onKeyPress/measureWrapper)

propTypes 16 项(逐个比对):

value / onChange / labelExtractor / text / onChangeText / editable /
tagColor / tagTextColor / tagContainerStyle / tagTextStyle /
inputDefaultWidth / inputColor / inputProps / maxHeight /
onHeightChange / scrollViewProps

(前 5 项 value / onChange / labelExtractor / text / onChangeText 是 isRequired)

defaultProps 6 项(清单 + 精确值):

键值
editabletrue
tagColor'#dddddd'
tagTextColor'#777777'
inputDefaultWidth90
inputColor'#777777'
maxHeight75

★★★★ PureComponent 的精确判据

class TagInput<T> extends React.PureComponent<…>   // index.js L106

⇒ TagInput.prototype.isPureReactComponent === true ✓

NOTE | TagInput.prototype.isPureReactComponent = true
PASS | ★★★★ 它是 PureComponent(isPureReactComponent === true)

⇒ 这条判据比"typeof 是 function"精确得多 —— 它区分了 Component 与 PureComponent ✓

★★★★ 方法归属:坑里的"三档规则"这次三档齐全

同一个类里,方法有三种归属方式,实测结果:

归属方式本库的例子实测
原型方法(xxx() {})render / componentWillReceiveProps / componentWillUpdate在 prototype 上 ✓
箭头类字段(xxx = () => {})measureWrapper / onBlur / onKeyPress / focus / removeIndex / scrollToEnd / tagInputRef / scrollViewRef / onScrollViewContentSizeChange / onLayoutLastTag只在实例上,不在 prototype ✓
constructor 内绑定(本库没有)—

实测(两条方向相反的断言都过):

NOTE | prototype 上的成员 = componentWillReceiveProps, componentWillUpdate, render
PASS | ★★★ 3 个方法在 prototype 上(render / cWRP / cWU)
NOTE | 箭头字段里错误地出现在 prototype 上的 = (无)
PASS | ★★★★ 箭头类字段【不在】prototype 上

NOTE | 实例是否可得 = true
PASS | ★★★★ 5 个箭头字段在【实例】上都存在 | 期望=5 | 实际=5
PASS | ★★★★ 而 prototype 上没有 focus
PASS | ★★★★ 而 prototype 上没有 removeIndex
PASS | ★★★★ 而 prototype 上没有 scrollToEnd

⇒ ⇒ 同一组方法:「实例上有」+「prototype 上没有」两条都成立,才是完整证据 ✓✓
⇒ 如果只断言"实例上有",那么"它其实也在 prototype 上"这种情况就漏掉了。

★★★★ 三、static inputWidth 纯函数的 4 条判据(含边界)

源码(index.js L145-L158):

static inputWidth(text, spaceLeft, inputDefaultWidth, wrapperWidth) {
  if (text === "") {
    return inputDefaultWidth;
  } else if (spaceLeft >= 100) {
    return spaceLeft - 10;
  } else {
    return wrapperWidth;
  }
}

实测 4 条全 PASS:

#调用期望(手推)实测
1inputWidth("", 0, 90, 1320)90(走第一分支)✅
2inputWidth("abc", 150, 90, 1320)140(spaceLeft − 10)✅
3inputWidth("abc", 50, 90, 1320)1320(走 wrapperWidth)✅
4inputWidth("abc", 100, 90, 1320)90(边界 100 满足 >= 100,100 − 10 = 90,不是 wrapperWidth)✅

⇒ 第 4 条最有价值:spaceLeft = 100 时,100 − 10 = 90 恰好等于 inputDefaultWidth = 90
—— 如果只测第 2、3 条,看不出这个"两个分支给出相同数字"的巧合;
边界值单独测一次,才知道它走的是哪个分支 ✓

★★★★★ 四、渲染证据:3 处标签文本 + 2 个 TextInput

页面里放了两个 TagInput:E1 有 2 个标签、E2 有 1 个标签。

布局 dump 实测:

✓ [Text] 「TGI 标签一 ×」 w=236 h=49 x=78  y=1244
✓ [Text] 「TGI 标签二 ×」 w=237 h=49 x=371 y=1244
✓ [Text] 「TGI 单个标签 ×」 w=278 h=49 x=78 y=1536

TextInput#TextInput(68) [639,1215,909,1269] clickable longClickable scrollable
TextInput#TextInput(94) [389,1507,809,1561] clickable longClickable scrollable

从这些数字能读出四件事 ✓✓:

观察结论
TGI 标签一 × 与 TGI 标签二 × 的 y 都是 1244两个标签在同一行(横向排列)✓
x = 78 与 371第二个标签在第一个右边(371 − 78 = 293)⇒ 横向排布 ✓
标签文本末尾都带 ×库自动加的删除符号(见下)
两个 TextInput 都在标签之后x = 639(E1,两个标签之后)、x = 389(E2,一个标签之后)⇒ 输入框紧跟最后一个标签 ✓

× 是从哪来的?—— 回源码找到了根因

dump 里看到标签文本带 ×,于是回去看 Tag 的 render()(index.js L396-410):

tagLabel = (
  <Text style={[styles.tagText, {color: this.props.tagTextColor}, this.props.tagTextStyle]}>
    {this.props.label}
    &nbsp;&times;          {/* ← ★ JSX 实体 &times; = × */}
  </Text>
);

⇒ ⇒ 这个 × 是库用 JSX 实体 &times; 硬编码进去的,不可配置 ✓
⇒ ⇒ 所以"标签文本里带 ×"不是我的数据带进来的,是库的行为 ✓

这一步的方法论:dump 里出现"预期之外的字符"时,不要急着怀疑自己的数据 ——
回源码找那个字符串的来源。这次找到的是 JSX 实体 &times;(而不是 "×" 字面量),
说明作者是有意用 HTML 实体写的,也说明无法通过 prop 去掉它。

⚠️ placeholder="Start typing" 没有出现在 dump 里 ——
placeholder 是 TextInput 的属性而不是布局文本节点,ui layout 不显示它。
⇒ 这与"accessibilityLabel 不进 dump"是同一类现象 ⇒ 如实记"未观察到" ✓

★★ 五、其余预检结论

预检项结果
dependenciesinvariant ^2.2.2 + prop-types ^15.5.10(prop-types 宿主已有,invariant 需装)
peerDependencies✅ 只有 react / react-native
createClass✅ 精确命中 0、裸词也 0
this.refs / mixins / getDefaultProps / ListView / measure()✅ 全部空
componentWillReceiveProps 2 处⚠️ React 19 已移除 ⇒ 不会执行(外部改 value 时的内部同步逻辑会失效,但本页由父组件驱动,无影响)
TextInput 15 处✓ 核心组件
onLayout 9 处✓ 用于测量标签换行位置
TouchableOpacity / TouchableWithoutFeedback✓(点击标签删除、点空白区域聚焦输入框)

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述


六、接入与预检(要点)

npm install "git+https://atomgit.com/oh-react-native/react-native-tag-input.git#0.0.21-ohos-1.0.0" --ignore-scripts
# 依赖:invariant(需装)+ prop-types(宿主已有)
# 还需要 ViewPropTypes / Text.propTypes 的 polyfill(工程里已有)

七、交付包质量与基线说明

类别结果
交付包内容单文件 index.js(13437 B / 487 行),10 个文件
⚠️ 老 APIViewPropTypes.style ×2、Text.propTypes.style ×2 ⇒ 需 polyfill
⚠️ 平台断言invariant(Platform.OS === "ios", …) ⇒ 但永不执行(调用处做了判断)
⚠️ 内部路径import type … from 'react-native/Libraries/…' ⇒ import type 会被消除
⚠️ 生命周期componentWillReceiveProps ×2 ⇒ React 19 已移除,不执行
spec.json⚠️ 缺 upstreamCommit
validation⚠️ "build-pass-device-pending"
⚠️ 声明的基线reactNative: "0.88.0" + rnoh: "0.84.4" ⇒ 两字段自相矛盾
备注库代码零改动

关于基线:本次验证在 RN 0.84.1 + RNOH 0.84.3 上完成。
本库零原生代码、平台差异只体现在 Platform.OS 的两处(且都不影响鸿蒙)⇒ 结论跨基线成立 ✓


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

8.1 用这个库要知道的

事项说明
★★★★★ TagInput 是 PureComponentprototype.isPureReactComponent === true
★★★★★ propTypes 16 项、defaultProps 6 项前 5 项 isRequired;默认值 '#dddddd' / '#777777' / 90 / 75
★★★★★ 方法归属分两档render/cWRP/cWU 在 prototype;focus/removeIndex/scrollToEnd 等 10 个箭头字段只在实例上
★★★★ × 是硬编码的Tag 的 render() 里写了 &nbsp;&times; ⇒ 无法通过 prop 去掉
★★★★ static inputWidth 是纯函数text === '' ⇒ inputDefaultWidth;spaceLeft >= 100 ⇒ spaceLeft − 10;否则 wrapperWidth
★★★ 需要 ViewPropTypes / Text.propTypes polyfillRN 0.44+ 已移除,本库仍在用
★★★ invariant(Platform.OS === 'ios') 不会在鸿蒙执行调用处 onBlur={Platform.OS === 'ios' ? this.onBlur : undefined}
★★ componentWillReceiveProps 不执行React 19 已移除 ⇒ 外部改 value 时的内部同步失效
★★ placeholder 不会出现在布局 dump 里它是属性而不是布局文本节点
★★ 依赖 invariant需要装(prop-types 宿主已有)

8.2 本次验证的边界

  1. ★★★ 未验证交互(点 × 删标签、Backspace 删最后一个、点空白聚焦——onChange/onKeyPress 未被真实触摸/按键触发);
  2. ★★★ 未验证标签自动换行(maxHeight: 75 的截断与 ScrollView 滚动);
  3. ★★ 未验证 onHeightChange / scrollViewProps / inputProps 等透传 prop;
  4. ★★ 未验证 componentWillReceiveProps 缺失带来的实际影响(外部改 value 时的行为);
  5. 未验证 Tag 的 onPress 删除是否真的把标签移除了;
  6. 未在 RN 0.88.0 / RNOH 0.84.4 上复验;
  7. 未测其它屏幕宽度(windowWidth 在模块加载时取自 Dimensions.get('window'),不会随旋转更新);
  8. 未做跨平台对照。

库代码未改动。


九、常见问题

Q1:它在 RN 0.84 上能跑吗?

能,零 FAIL。 23 条判据全 PASS:PureComponent 判定、propTypes 16 项、defaultProps 6 项精确值、
方法归属两档、inputWidth 4 条、3 处标签文本与 2 个 TextInput 都渲染出来;LogBox 无通知。

Q2:它用了 ViewPropTypes,会不会崩?

会崩 —— 但有 polyfill 就不崩。 工程里已有 polyfills/text-prop-types.js(在 index.js 第 28 行导入),
它同时补了 ViewPropTypes 与 Text.propTypes ⇒ 直接复用即可 ✓

Q3:invariant(Platform.OS === 'ios', …) 在鸿蒙上会抛错吗?

不会,因为它永远不会被调用:

onBlur={Platform.OS === "ios" ? this.onBlur : undefined}   // 鸿蒙上传 undefined
onBlur = (event) => {
  invariant(Platform.OS === "ios", "…");                    // ← 永不到达
}

⇒ 判断"某个断言会不会执行",要看它的调用条件,而不是看它写在哪 ✓

Q4:它 import 了 react-native/Libraries/... 内部路径,Metro 能过吗?

能,因为那是 import type(Flow 类型导入),转译时被整体消除,不产生 require ✓

Q5:标签后面的 × 能去掉吗?

不能(通过 prop)。它在 Tag 的 render() 里被硬编码:

<Text>{this.props.label}&nbsp;&times;</Text>

⇒ 想改只能 fork 这个库,或者用 labelExtractor 返回一个 React 元素
(源码里有分支:React.isValidElement(this.props.label) 为真时直接渲染、不加 ×)✓ ——
这是"想去掉 ×"的正规做法。

Q6:为什么 focus() / removeIndex() 在 prototype 上找不到?

因为它们是箭头类字段(focus = () => {...}),在构造时绑定到实例上,
不在 prototype 上。要用 ref 拿实例再调:

const ref = useRef(null);
<TagInput ref={ref} … />
ref.current.focus();
ref.current.removeIndex(0);
ref.current.scrollToEnd();

实测:实例上 5 个箭头字段都在、prototype 上都没有 ✓

Q7:inputWidth 是怎么算的?

static inputWidth(text, spaceLeft, inputDefaultWidth, wrapperWidth) {
  if (text === "")              return inputDefaultWidth;    // 空输入 ⇒ 默认宽度
  else if (spaceLeft >= 100)    return spaceLeft - 10;       // 剩余够 ⇒ 占剩余减 10
  else                          return wrapperWidth;         // 剩余不够 ⇒ 换行占满
}

⇒ 实测 4 条(含边界 spaceLeft = 100)全 PASS ✓

Q8:placeholder 为什么在 dump 里看不到?

因为 placeholder 是 TextInput 的属性,不是布局文本节点,ui layout 不显示它。
⇒ 想看它得用别的工具(比如无障碍树),布局 dump 只能看到真正渲染的 Text ✓


小结

react-native-tag-input 是标签输入框(标签 + × 删除 + 末尾 TextInput),
单文件 487 行、零原生代码、23 条判据全 PASS、零 FAIL。

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

  1. ★★★★★ 三个"预检命中"都能在动手前判定为安全 —— 关键是读上下文。

    • ViewPropTypes.style / Text.propTypes.style ⇒ 工程里已有 polyfill ✓
    • invariant(Platform.OS === "ios", …) ⇒ 调用处 onBlur={Platform.OS === 'ios' ? … : undefined},该函数永不执行 ✓
    • import … from 'react-native/Libraries/…' ⇒ 是 import type,转译时被消除 ✓
      ⇒ 教训:看到"老 API / 平台断言 / 内部路径"先别改代码 ——
      先找它会不会被执行 / 会不会被解析。本库代码最终零改动。
  2. ★★★★★ 方法归属要"两个方向都断言"才是完整证据。

    PASS | 3 个方法在 prototype 上(render / cWRP / cWU)
    PASS | 箭头类字段【不在】prototype 上
    PASS | 5 个箭头字段在【实例】上都存在
    PASS | 而 prototype 上没有 focus / removeIndex / scrollToEnd
    

    ⇒ 只断言"实例上有"会漏掉"它其实也在 prototype 上";两个方向都查才完整 ✓

  3. ★★★★★ PureComponent 有精确判据:prototype.isPureReactComponent === true。
    ⇒ 比"typeof 是 function"精确得多 —— 它把 Component 与 PureComponent 区分开了 ✓

  4. ★★★★ inputWidth 的边界值最有价值:
    spaceLeft = 100 时 100 − 10 = 90,恰好等于 inputDefaultWidth。
    ⇒ 不单独测边界,就看不出"它走的是第二个分支" ✓

  5. ★★★★ dump 里出现"预期之外的字符",要回源码找来源。
    标签文本带 × ⇒ 回源码发现是 JSX 实体 &times; 硬编码的(不可配置)
    ⇒ 而且源码里还有分支:labelExtractor 返回 React 元素时不加 × ——
    这是"想去掉 ×"的正规做法 ✓

  6. ★★★ placeholder / accessibilityLabel 这类"属性"不进布局 dump。
    本轮 placeholder="Start typing" 未命中 ⇒ 如实记"未观察到",不写成"没生效" ✓


本篇用到的库

项内容
三方库react-native-tag-input(上游 0.0.21 的鸿蒙适配版)
适配仓库https://atomgit.com/oh-react-native/react-native-tag-input
适配 TAG0.0.21-ohos-1.0.0
需要 HAR / 权限 / ohpm都不需要(纯 JS)
库类型标签输入框(标签 + × 删除 + 末尾 TextInput)
运行时依赖invariant(需装)+ prop-types(宿主已有)
导出形态只有默认导出 TagInput(class,extends React.PureComponent)
需要 polyfillViewPropTypes / Text.propTypes(工程里已有)
static 纯函数TagInput.inputWidth(text, spaceLeft, inputDefaultWidth, wrapperWidth)
许可证MIT
上游仓库https://github.com/jwohlfert23/react-native-tag-input
宿主工程RNOH084Demo(测试页 rnAppKey = TagInputTestApp)
npm install "git+https://atomgit.com/oh-react-native/react-native-tag-input.git#0.0.21-ohos-1.0.0" --ignore-scripts
npm install invariant --ignore-scripts --no-audit --no-fund
# 另需 ViewPropTypes / Text.propTypes 的 polyfill(工程里已有)
import TagInput from 'react-native-tag-input';

const [tags, setTags] = useState(['标签一', '标签二']);
const [text, setText] = useState('');
const ref = useRef(null);

<TagInput
  ref={ref}
  value={tags}
  onChange={(next) => setTags(next)}
  text={text}
  onChangeText={(t) => setText(t)}
  labelExtractor={(tag) => String(tag)}   // 必填
  tagColor="#d8f0d8"
  tagTextColor="#004400"
  inputDefaultWidth={90}
  maxHeight={75}
/>

// 实例方法(箭头类字段 ⇒ 不在 prototype 上,用 ref 调)
ref.current.focus();
ref.current.removeIndex(0);
ref.current.scrollToEnd();

// 静态纯函数
TagInput.inputWidth('', 0, 90, 1320);       // 90
TagInput.inputWidth('abc', 150, 90, 1320);  // 140
TagInput.inputWidth('abc', 50, 90, 1320);   // 1320
TagInput.inputWidth('abc', 100, 90, 1320);  // 90(边界走 >= 分支)

// ⚠️ 它是 PureComponent(prototype.isPureReactComponent === true)
// ⚠️ 需要 ViewPropTypes / Text.propTypes 的 polyfill
// ⚠️ 标签末尾的 × 是硬编码的(&times;),想去掉就让 labelExtractor 返回 React 元素
// ⚠️ focus / removeIndex / scrollToEnd 是箭头类字段(不在 prototype 上)
// ⚠️ placeholder 不会出现在布局 dump 里
# 换页启动测试页 —— force-stop 不能省
hdc shell aa force-stop com.rnoh084.demo
hdc shell aa start -b com.rnoh084.demo -a EntryAbility --ps rnAppKey TagInputTestApp

判据的复现方式

# ① 23 条判据(零 FAIL)
hdc shell "hilog -x | grep tgi-test" | Select-String 'PASS|FAIL|SUMMARY|NOTE'
#    ⇒ SUMMARY | 合计 23/23 通过,失败 0
#    ⇒ PureComponent / propTypes 16 项 / defaultProps 6 项精确值
#    ⇒ 方法归属两个方向都过 / inputWidth 4 条
# ② 渲染证据
devecocli ui layout | Select-String 'TGI 标签|TextInput'
#    ⇒ 「TGI 标签一 ×」x=78 y=1244、「TGI 标签二 ×」x=371

验证环境

项版本
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 = 39vp
宿主依赖invariant(新装)+ prop-types(已有)+ 已有 ViewPropTypes/Text.propTypes polyfill
宿主 HAP 产物entry-default-signed.hap
本次构建一次成功:assembleHap 3 分 37 秒(打包前两条 JSX 自查,风险行 = 0)
验证规模23/23 全 PASS、零 FAIL;PureComponent 判定;propTypes 16 项 + defaultProps 6 项精确值;方法归属两档双向验证;inputWidth 4 条(含边界);文本 3 处 + TextInput 2 个;LogBox 无通知;4 张截图互异

⚠️ 基线说明:交付包 spec.json 声明 RN 0.88.0 + RNOH 0.84.4(两字段自相矛盾),本次验证在 RN 0.84.1 + RNOH 0.84.3 上完成。
本库零原生代码,平台差异只在两处 Platform.OS(都不影响鸿蒙)⇒ 结论跨基线成立 ✓


相关社区与项目地址

项目地址
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

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐