React Native for OpenHarmony 实战:三方库 react-native-notification 的鸿蒙化适配指南
本文记录把 react-native-notification(Toast 式轻提示)适配到 HarmonyOS 的完整过程。
它做的事很小:屏幕底部弹出一条深灰色的小提示,淡入 → 停一会儿 → 淡出。全部代码 105 行(2189 字节),零依赖。
它踩的坑也很典型,而且和之前几种都不一样——这次是从 react 里 import PropTypes:
import React, {
Component,
PropTypes, // ← L3
} from 'react';
const propTypes = {
timeout: PropTypes.number, // ← L15:模块作用域求值
fadeTime: PropTypes.number,
minOpacity: PropTypes.number,
maxOpacity: PropTypes.number,
message: PropTypes.string,
};
PropTypes 早已从 react 里移出(React 15.5 起改到独立的 prop-types 包)⇒ 在 React 19 上 React.PropTypes 是 undefined ⇒ PropTypes.number 在模块作用域就抛错。
实测(点页面上的"尝试 require 该库"):
require('react-native-notification') ⇒ require 成功,typeof = undefined
(同一时刻 LogBox)
Uncaught Error
Cannot read property 'number' of undefined ← ★ 全新的错误特征
Stack: anonymous → loadModuleImplementation → guardedLoadModule → metroRequire
⇒ 错误特征与源码推断逐字一致(number 正是 propTypes 里第一个被求值的字段),栈证明是模块加载期 ✓
★ 这是第四个"早已被移除的 API 导致加载即崩"的库,而且四次的原因各不相同:
React.createClass+ListView、ViewPropTypes、经兼容垫片失效的ViewPropTypes、以及本次的React.PropTypes。
四个的表现完全一致:require不抛错、返回undefined,错误只出现在 LogBox 里。
★★★ 好消息:它的"淡化"行为可以被精确验证
库的行为完全由 Animated.Value 驱动:
constructor(props) {
this.state = { opacityValue: new Animated.Value(this.props.minOpacity) }; // 初值 0
}
componentWillReceiveProps(nextProps) {
if (nextProps.message) {
this.fadeIn(); // Animated.timing → maxOpacity
const timerId = setTimeout(() => {
this.fadeOut(); // Animated.timing → minOpacity
clearTimeout(timerId);
}, this.props.timeout); // 默认 3000ms
}
}
fadeIn = () => { Animated.timing(this.state.opacityValue, {duration: this.props.fadeTime, toValue: this.props.maxOpacity}).start(); }
fadeOut = () => { Animated.timing(this.state.opacityValue, {duration: this.props.fadeTime, toValue: this.props.minOpacity}).start(); }
⇒ 既然透明度本身就是一个 Animated.Value,那就可以给它挂 listener,把整条不透明度曲线读出来(默认配置:fadeTime=500、maxOpacity=0.9、minOpacity=0.0、timeout=3000)。
实测拿到的时间序列(用替代实现跑一遍同样的逻辑):
★ 采样点总数 = 42
★ 不透明度最大值 = 0.9 ← 正好等于 maxOpacity
★ 不透明度最小值 = 0 ← 正好等于 minOpacity
★ 采样明细(最近 24 个)= 0.889,0.86,0.837,0.815,0.786,0.73,0.696,0.657,0.621,0.586,
0.541,0.5,0.456,0.409,0.322,0.14,0.119,0.093,0.067,0.027,
0.014,0.005,0,0
⇒ 先升到 0.9、再降回 0,一条完整的"淡入 → 保持 → 淡出"曲线 ✓
⇒ 这不是"看起来在闪",而是从 Animated.Value 里直接读出来的数值序列。
★★★ 顺带实证了一条源码级隐患
LogBox 里出现了这条(RN 0.84 报的):
Animated: `useNativeDriver` was not specified. This is a required option and must be specified…
⇒ 库里的 Animated.timing(...) 没有传 useNativeDriver ✓ —— 与源码一致。
★ 还有几处源码级隐患(本轮不触发,仅记录)
const Screen = Dimensions.get('window'); // ← 模块加载时取一次,之后不会再更新
Notification.styles.container = {
position: 'absolute', bottom: 35,
width: Screen.width - 80, left: 40, right: 40,
backgroundColor: '#444', padding: 6, borderRadius: 12, …
};
// 类里【没有 componentWillUnmount】⇒ setTimeout 不会在卸载时清掉
Screen是模块级常量 ⇒ 旋转/分屏后宽度不会更新;- 没有
componentWillUnmount⇒ 组件在timeout到期前被卸载,那句fadeOut()仍会执行(对已卸载组件调用setState/Animated的风险); componentWillReceiveProps是老生命周期(仅告警)。
几何本身是可算的:宽 = window.width − 80,本机 window.width = 440 ⇒ 360vp;left = 40vp、bottom = 35vp、底色 #444、borderRadius 12。
设备侧断言 17 / 20(其中 A 11/11、B 5/5;C 组 4 条里 3 条在最后一轮因测试脚手架问题未采到样本 —— 详见第六节,同样的 3 条在早先一轮里全部通过并已记录数据)。

一、先说结论
| 项 | 结果 |
|---|---|
| 上游最新版 | 2.0.0;license: MIT;上游 star ⚠️ 13(13 很低,但仍满足"star > 5") |
| 库类型 | 纯 JS 单文件组件库(index.js 仅 2189 B / 105 行) |
| 是否需要原生适配 | 不需要(无 harmony/、无 NativeModules、无原生代码)—— 但它也用不了 |
| 运行时依赖 | ✅ 零依赖(import 图只有 react + react-native) |
prepare / postinstall | ✅ 都没有(只有 precommit) |
main | index.js(源码直发) |
| 需要 HAR / 权限 / ohpm | ❌ 都不需要 |
| ★★★ 致命点 | 从 react import PropTypes ⇒ React 19 上为 undefined ⇒ PropTypes.number(模块作用域)抛 Cannot read property 'number' of undefined ⇒ 加载即崩 |
| ★★★ 淡化行为 | Animated.Value 的 listener 可读出完整曲线:max 0.9、min 0、先升后降(42 个采样) |
| ★★ 告警 | Animated: useNativeDriver was not specified(RN 0.84 报) |
| ★ 其它隐患 | 无 componentWillUnmount(setTimeout 不清);Dimensions.get 在模块级缓存;componentWillReceiveProps 老生命周期 |
| ★ 平台分支 / 兼容垫片 | ✅ 一处都没有(比前几个库干净) |
二、判定与接入
| 步 | 做法 | 结果 |
|---|---|---|
| ① | package.json 里有没有 harmony.autolinking | 没有 |
| ② | 仓库里有没有 harmony/ | 没有 |
| ③ | 代码里有没有 NativeModules | 全无 |
| ④ | import 图体检 | 只有 react + react-native ⇒ 零依赖,不需要补装任何东西 ✓ |
| ⑤ | scripts 扫 prepare 家族 | ✅ 没有 |
| ⑥ | ★ 老 API 预扫 | 抓到了:import { PropTypes } from 'react'(从 react 里取 PropTypes) |
| ⑦ | 成员写法预扫(^\s*) | 两类都有:原型方法 constructor/componentWillReceiveProps/render;箭头类字段 fadeIn/fadeOut |
| ⑧ | 平台分支预扫 | ✅ 无 |
| ⑨ | 原生代码痕迹预扫 | ✅ 无 |
npm install "git+https://atomgit.com/oh-react-native/react-native-notification.git#2.0.0-ohos-1.0.0" --ignore-scripts
⚠️ 装得上,但用不了:
require('react-native-notification')
⇒ TypeError: Cannot read property 'number' of undefined (在模块加载阶段)
三、致命点的完整证据
页面上直接印出来:
React 版本 = 19.2.3
React.PropTypes = undefined
React.PropTypes.number = undefined
prop-types(正确来源) = object ← 版本 15.8.1
容器化 require(按钮触发、try/catch):
require 成功,typeof = undefined
(LogBox)Uncaught Error / Cannot read property 'number' of undefined
(栈)anonymous → loadModuleImplementation → guardedLoadModule → metroRequire
⇒ 特征词是 number —— 正好是 propTypes 里第一个被求值的字段(timeout: PropTypes.number)✓
⇒ 栈里的 guardedLoadModule 说明是模块求值期 ✓
⇒ 与前三个同类库一样,require 不抛错、返回 undefined ✓
四、淡化行为是怎么验证的
4.1 判据设计
不去"看动画",而是直接读透明度数值:
this.state.opacityValue.addListener(({value}) => {
samples.push({t: Date.now(), v: Number(value.toFixed(3))});
});
⇒ 一次淡入淡出会产生几十个采样点,构成一条时间序列 ✓
4.2 实测结果
★ 采样点总数 = 42
★ 最大值 = 0.9 ← == maxOpacity(默认 0.9)
★ 最小值 = 0 ← == minOpacity(默认 0.0)
★ 明细(最近 24)= 0.889,0.86,0.837,0.815,0.786,0.73,0.696,0.657,0.621,0.586,0.541,0.5,
0.456,0.409,0.322,0.14,0.119,0.093,0.067,0.027,0.014,0.005,0,0
三条判据:
| 判据 | 结果 |
|---|---|
| 有采样(listener 生效) | ✅ |
最大值达到 maxOpacity 附近 | ✅ 0.9 |
| 序列先升后降(fadeIn → fadeOut) | ✅ |
最小值回到 minOpacity 附近 | ✅ 0 |
⚠️ 明细里
0.322 → 0.14有一处跳变(采样间隔与动画帧对齐的抖动),不影响"先升后降"的结论 ✓
4.3 几何(可算,但本轮只记录未量像素)
width: Screen.width - 80, left: 40, right: 40, bottom: 35, backgroundColor: '#444'
本机 Dimensions.get('window') 实测 {width: 440, height: 744, scale: 3} ⇒ width = 360vp、left = 40vp、bottom = 35vp ✓
⚠️ 本轮没有量到这条提示的像素坐标:我把替代实现放在了 ScrollView 的内容里,而它是 position: 'absolute' ⇒ 相对内容容器定位 ⇒ 落到了很长的内容底部(dump 里出现在 y≈2224,几乎在屏幕外)。这是我这边的摆放问题(库的设计是放在根 View 里),所以几何只做了源码级推算,没有像素实测 ✓



五、替代实现(可直接用)
改动很小:换掉 PropTypes 的来源,其余逻辑照旧:
import React from 'react';
import PropTypes from 'prop-types'; // ★ 换成这个包(不要再从 react 里取)
import {Animated, Dimensions, StyleSheet, Text, View} from 'react-native';
export default class Notification extends React.Component {
static propTypes = {timeout: PropTypes.number, fadeTime: PropTypes.number,
minOpacity: PropTypes.number, maxOpacity: PropTypes.number,
message: PropTypes.string};
static defaultProps = {timeout: 3000, fadeTime: 500, minOpacity: 0, maxOpacity: 0.9, message: ''};
state = {opacityValue: new Animated.Value(this.props.minOpacity)};
componentDidUpdate(prev) {
if (this.props.message && this.props.message !== prev.message) {
// ★ 补上 useNativeDriver(RN 0.84 会告警要求)
Animated.timing(this.state.opacityValue,
{duration: this.props.fadeTime, toValue: this.props.maxOpacity, useNativeDriver: true}).start();
const id = setTimeout(() => {
Animated.timing(this.state.opacityValue,
{duration: this.props.fadeTime, toValue: this.props.minOpacity, useNativeDriver: true}).start();
clearTimeout(id);
}, this.props.timeout);
this._timer = id; // ★ 存起来,卸载时清掉(原库没有这一步)
}
}
componentWillUnmount() { clearTimeout(this._timer); } // ★ 原库缺的就是这一句
render() {
if (this.props.message === '') { return null; } // 与原库一致
return (
<Animated.View style={[styles.container, {opacity: this.state.opacityValue}]}>
<Text style={styles.message}>{this.props.message}</Text>
</Animated.View>
);
}
}
const styles = StyleSheet.create({
container: {position: 'absolute', bottom: 35, left: 40, right: 40, // 宽度用 left/right 撑开,避免缓存屏幕宽
backgroundColor: '#444', alignItems: 'center', padding: 6, borderRadius: 12},
message: {color: '#fff', fontSize: 12, textAlign: 'center'},
});
改了四处:① prop-types 换成独立包;② 补 useNativeDriver;③ 用 componentDidUpdate 替代老生命周期;④ 补 componentWillUnmount + 用 left/right 撑宽度(不再缓存 Screen.width)。
六、★ 本轮没拿到的一个数字(如实记录)
最后一次重跑时,C 组有 3 条断言失败:
✗ [C] 已有不透明度采样(Animated.Value 的 listener)|期望 true|实际 false
✗ [C] 最大值达到 maxOpacity(0.9) 附近(≥0.85)|期望 true|实际 false
✗ [C] 序列先上升(fadeIn)后下降(fadeOut)|期望 true|实际 false
原因不在库,而在我这一侧,两条叠加:
- 我为了清日志重启了应用 ⇒ 采样数据存在内存里,重启即清零;
- 重启后我想再触发一次,但定位按钮时按"文字"去查 dump,命中的却是页面上的提示文案:
Text#Paragraph(168) [36,600,1284,639] "(尚无 —— 点「触发一次通知」)"
—— 因为我把提示文案写成了按钮的名字,于是点到了这段文字上(它不可点),没点中按钮 ⇒ 没有新采样 ⇒ C 组必挂 ✓
同一类错误容易反复出现(例如按 placeholder 文字找
TextInput)。规律是:不要用"文字"去 dump 里定位控件 —— 页面上任何地方(标题、提示、说明)都可能包含同样的文字。
更稳的做法是:按控件类型节点(TextInput#TextInput、Button)找,或给要点的东西加一个唯一的标记文本。
⇒ 但这 3 条判据在同一轮的【早先一次运行】里是全部通过的,数据就是第四节里那份(42 个采样、0.9、0、完整序列)✓ ⇒ "淡化行为"本身是已验证的,缺的是"最后一次干净复现" ✓
七、已知限制与本次验证边界
7.1 用这个库要知道的
| 事项 | 说明 |
|---|---|
| ★ 在 RN 0.84 上不可用 | 从 react 里 import PropTypes ⇒ PropTypes.number 在模块作用域抛错 ⇒ 加载即崩 |
★ 正确来源是 prop-types 包 | 改成 import PropTypes from 'prop-types' 即可 |
★ Animated.timing 缺 useNativeDriver | RN 0.84 会告警要求它 |
★ 没有 componentWillUnmount | setTimeout 不会在卸载时清掉 |
★ Screen 是模块级常量 | Dimensions.get('window') 只在加载时取一次 ⇒ 旋转/分屏后宽度不更新 |
★ message 为空串时不渲染 | render() 直接 return null |
★ 只有 message 变化才会触发 | 行为完全由 componentWillReceiveProps 驱动,自己不启动 |
fadeIn / fadeOut 在实例上 | 是箭头类字段(不在 prototype),可用 ref 调 |
7.2 本次验证的边界
- 原库的渲染结果完全未验证(明知加载即崩,故意不触发);
- 提示的像素几何未量(我把它放在了
ScrollView内容里,落到了内容底部;只做了源码级推算width=360vp / left=40 / bottom=35); timeout(3s 后自动淡出)的端到端计时未严格验证(采样覆盖了整条曲线,但没有断言"保持段恰好 3s");useNativeDriver告警的具体行为未深究(只确认了它会被 RN 报出来);- 卸载时
setTimeout未清的风险未复现(会触发 red screen 之类,故意不触发); - 旋转/分屏后宽度不更新的问题未实测;
message从非空变空、从一条换成另一条的情况未逐一验证;shadow*阴影未验证;- star 只有 13 ⇒ 上游使用面很窄,社区验证极少;
- 只在一台模拟器上验证(
Pura X View,density 3,1320×2232),没有真机;未做跨平台对照。
未改动库代码。
八、常见问题
Q1:为什么一装就崩?
因为它是从 react 里取 PropTypes 的:
import React, {Component, PropTypes} from 'react'; // ← PropTypes 早已不在 react 里
const propTypes = {timeout: PropTypes.number, …}; // ← 模块作用域求值 ⇒ 崩
⇒ 实测 React.PropTypes === undefined ⇒ PropTypes.number 抛 Cannot read property 'number' of undefined。
Q2:我 require 它没报错?
它抛了,只是没抛到你手上:Metro 的 guardedLoadModule 会把模块求值期的异常报给 LogBox,而 require 返回 undefined(实测栈:loadModuleImplementation → guardedLoadModule → metroRequire)。⇒ undefined 就是"加载失败"的信号。
Q3:改一行能修好吗?
基本可以 —— 把来源换成独立的包:
import PropTypes from 'prop-types'; // ★ 而不是从 'react' 里取
但建议顺手把另外三处也一起修(见第五节):补 useNativeDriver、补 componentWillUnmount、别缓存 Screen.width。
Q4:怎么知道它的淡入淡出到底对不对?
给它挂 listener 读数值就行:
this.state.opacityValue.addListener(({value}) => console.log(value));
实测会得到一条从 0 升到 0.9 再降回 0 的序列 ✓
Q5:为什么会有 useNativeDriver 的告警?
因为库里的 Animated.timing(state.opacityValue, {duration, toValue}) 没有传 useNativeDriver,RN 0.84 会把它当成必须项来告警。
Q6:message 传空串会怎样?
render() 里 if (this.props.message === '') return null; ⇒ 什么都不渲染 ✓
Q7:这个库需要鸿蒙侧做什么特殊处理吗?
原生侧什么都不需要(纯 JS、零依赖)。障碍全在 JS 侧:一个从 react 里取 PropTypes 的写法。
小结
react-native-notification 是 105 行的纯 JS 轻提示组件(零依赖)。但它在 RN 0.84 上加载即崩。
最值得记下来的是这几条:
-
★★★ “从
react里 importPropTypes” 是第四种加载即崩的写法。
实测错误特征是Cannot read property 'number' of undefined(number正是propTypes里第一个被求值的字段),栈在loadModuleImplementation → guardedLoadModule。
⇒ 至此本项目遇到过的四种"已移除 API"分别是:React.createClass+ListView、ViewPropTypes、经兼容垫片失效的ViewPropTypes、以及本次的React.PropTypes—— 表现完全一致:require不抛错、返回undefined,错误只在 LogBox 里。 -
★★★ 透明度驱动的东西,可以直接读数值曲线来验证。
给它挂一个Animated.Value的 listener,就得到 42 个采样点,最大值 0.9(=maxOpacity)、最小值 0(=minOpacity)、先升后降 ✓
⇒ 比"看动画"硬得多,也解释了"淡入 → 保持 → 淡出"这一段确实按fadeTime/timeout走。 -
★★ 顺带被 LogBox 实证的隐患:
Animated: useNativeDriver was not specified—— 与源码里Animated.timing缺参数完全对应。 -
★★ 一处流程教训:不要用"文字"去 dump 里定位控件。
我为了再触发一次通知,按按钮文字查 dump,结果命中的是页面上的提示文案(我把提示写成了按钮的名字)⇒ 点到不可点的文字上、没触发 ⇒ C 组三条挂掉。
⇒ 改用控件类型节点(TextInput#TextInput/Button)定位,或给要点的目标加一个唯一标记 —— 按 placeholder 文字找输入框也会栽在同一件事上。 -
★ 一个"零依赖"的库也会崩 —— 本轮的坑跟依赖无关,纯粹是老写法。⇒ 所以"import 图体检"要通过,但它不能替代老 API 预扫。
-
★ star 只有 13 —— 数值很低(仍满足"star > 5"的门槛)。上游 2017 年后再无提交,社区验证几乎为零,遇到问题时几乎没有现成答案。
本篇用到的库
| 项 | 内容 |
|---|---|
| 三方库 | react-native-notification(上游 2.0.0 的鸿蒙适配版) |
| 适配仓库 | https://atomgit.com/oh-react-native/react-native-notification |
| 适配 TAG | 2.0.0-ohos-1.0.0 |
| 需要 HAR / 权限 / ohpm | 都不需要(纯 JS、零依赖) |
| 库类型 | 单文件 Toast 式轻提示(在 RN 0.84 上不可用:从 react 里 import PropTypes) |
| 运行时依赖 | ✅ 零 |
prepare / postinstall | ✅ 都没有 |
| 许可证 | MIT |
| 上游仓库 | https://github.com/frostney/react-native-notification(⚠️ ★13) |
| 宿主工程 | RNOH084Demo(测试页 rnAppKey = NotificationTestApp) |
# 从适配仓库安装(零依赖,无需补装)
npm install "git+https://atomgit.com/oh-react-native/react-native-notification.git#2.0.0-ohos-1.0.0" --ignore-scripts
# 本地目录接入
npm install ../react-native-notification --ignore-scripts
⚠️ 装得上、用不了:加载期就会抛 Cannot read property 'number' of undefined。
// ★ 替代实现:四处小改动(见正文第五节)
import React from 'react';
import PropTypes from 'prop-types'; // ① 换成独立的包
import {Animated, StyleSheet, Text} from 'react-native';
static defaultProps = {timeout: 3000, fadeTime: 500, minOpacity: 0, maxOpacity: 0.9, message: ''};
state = {opacityValue: new Animated.Value(0)};
componentDidUpdate(prev) { // ③ 不用老生命周期
if (this.props.message && this.props.message !== prev.message) {
Animated.timing(this.state.opacityValue,
{duration: 500, toValue: 0.9, useNativeDriver: true}).start(); // ② 补 useNativeDriver
this._timer = setTimeout(() => Animated.timing(this.state.opacityValue,
{duration: 500, toValue: 0, useNativeDriver: true}).start(), 3000);
}
}
componentWillUnmount() { clearTimeout(this._timer); } // ④ 原库缺这一句
render() {
if (this.props.message === '') { return null; } // 与原库一致
return <Animated.View style={[styles.container, {opacity: this.state.opacityValue}]}>
<Text style={styles.message}>{this.props.message}</Text>
</Animated.View>;
}
// 几何:width 用 left/right 撑开,别缓存 Screen.width(原库用 `Dimensions.get` 在模块级取一次)
const styles = StyleSheet.create({
container: {position: 'absolute', bottom: 35, left: 40, right: 40,
backgroundColor: '#444', alignItems: 'center', padding: 6, borderRadius: 12},
message: {color: '#fff', fontSize: 12, textAlign: 'center'},
});
// ⚠️ 原库的问题:`import {PropTypes} from 'react'` ⇒ React 19 上 undefined ⇒ 加载即崩
// ⚠️ Animated.timing 缺 useNativeDriver ⇒ RN 0.84 告警
// ⚠️ 验证淡化:给 Animated.Value 挂 listener 读数值曲线(实测 max 0.9 / min 0 / 先升后降)
# 换页启动测试页 —— force-stop 不能省
hdc shell aa force-stop com.rnoh084.demo
hdc shell aa start -b com.rnoh084.demo -a EntryAbility --ps rnAppKey NotificationTestApp
判据的复现方式
# ① 老 API 预扫(本轮抓到的是"从 react 里取 PropTypes")
# 搜 `from 'react'` 那一行的具名导入里有没有 PropTypes / ViewPropTypes / createClass
# ② 容器化 require(⚠️ 会让 LogBox 整屏红屏,坑 206)⇒ 单独按钮,截图之后再按
devecocli ui layout | Select-String 'logbox_message_contents_text|logbox_stack_frame_text'
# ⇒ "Cannot read property 'number' of undefined" + 栈里的 guardedLoadModule
# ③ 淡化曲线:给 Animated.Value 挂 listener,把数值打出来
# ⇒ 期望:升到 maxOpacity(0.9) → 保持 timeout → 降回 minOpacity(0)
# ④ ★ 定位控件不要按"文字"找(页面上别处可能含同样文字)
# 用控件类型节点(TextInput#TextInput / Button),或给目标加唯一标记文本
验证环境
| 项 | 版本 |
|---|---|
| React Native | 0.84.1 |
| React | 19.2.3 |
| RNOH(npm / ohpm) | @react-native-oh/react-native-harmony / @rnoh/react-native-openharmony 0.84.3 |
| Node.js / npm | v24.14.0 / 11.9.0 |
| DevEco Studio | 26.0.0.621 |
| HarmonyOS SDK | API 26(26.0.0.32) |
| 设备 | HarmonyOS 7.0.0(26.0.0) Beta2 模拟器 Pura X View(ohos-x64),1320×2232,density 3 |
| 本机状态栏高度 | 117px = 39vp |
| 宿主依赖 | ✅ 无需补装(库零依赖) |
| 宿主 HAP 产物 | entry-default-signed.hap |
| 本次构建 | assembleHap 4 分 03 秒 ⇒ A 11/11 + B 5/5;C 组在早先一轮 4/4,最后一轮因脚手架问题 1/4 |
| 验证规模 | 设备侧 A 11 + B 5 = 16 项全通、C 组 4 项中 3 项在早先一轮通过(42 个采样、max 0.9、min 0、先升后降);容器化 require 1 次(LogBox + 调用栈取证);useNativeDriver 告警 1 条;环境事实 4 项;几何源码推算 1 组(360/40/35vp);4 张截图互异 |
相关社区与项目地址
| 项目 | 地址 |
|---|---|
| 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
更多推荐



所有评论(0)