React Native鸿蒙React Native内置组件 康复系统Day4~6
在前置的学习中,我已经完成了环境的配置,系统框架的简单搭建,在这三天的学习与实践中,我完善了这些方面:为列表清单集成完整的上拉加载、下拉刷新功能,实现数据的增量加载与实时刷新;同时添加多场景数据加载提示(含加载中、加载失败、无更多数据、空数据等状态),确保交互逻辑闭环,提示样式适配不同终端显示规范。报错代码:安装了与OpenHarmony不兼容的库,该库内部依赖特定平台模块,未适配OpenHarm
前置学习及实践成果 系统初步搭建
一、前置开发基础与核心优化目标
在 Day4~6 开发前,已完成React Native(以下简称 RN)环境配置与VR 康复系统框架搭建,本阶段核心目标是完善系统交互体验与稳定性,具体实现:
- 为训练场景列表集成上拉加载 + 下拉刷新功能,支持数据增量加载与实时刷新;
- 覆盖全场景数据加载提示(加载中、加载失败、无更多数据、空数据),确保交互逻辑闭环,且提示样式适配鸿蒙多终端显示规范;
- 解决开发中遇到的平台适配、组件兼容、状态管理等关键报错,保障系统稳定运行
二、报错与处理
1、第三方库兼容性问题
问题现象
使用react-native-pull-to-refresh库实现下拉刷新时,报错 “无法解析模块./lib/PullToRefreshView”,原因是该库未适配鸿蒙模块解析规则,依赖特定平台模块导致兼容性失效。
解决方案
替换为 RN 原生RefreshControl组件(已兼容 OpenHarmony),该组件可直接嵌入ScrollView或FlatList,支持自定义加载颜色与刷新逻辑,代码示例:
报错代码:
Error: Unable to resolve module ./lib/PullToRefreshView from D:\AtomGitRepo\AtomGitNews\node_modules\react-native-pull-to-refresh\index.js:
None of these files exist:
* node_modules\react-native-pull-to-refresh\lib\PullToRefreshView(.harmony.js|.native.js|.js|...)
安装了与OpenHarmony不兼容的库,该库内部依赖特定平台模块,未适配OpenHarmony的模块解析规则。
于是,使用React Native原生RefreshControl(OpenHarmony兼容):
<ScrollView
refreshControl={
<RefreshControl
refreshing={refreshing}
onRefresh={handleRefresh}
colors={['#1E88E5']}
/>
}
>
{/* 列表内容 */}
</ScrollView>
鸿蒙适配补充
-
若需使用其他三方库,优先选择
@react-native-oh-tpl/xxx前缀的鸿蒙补丁库(如@react-native-oh-tpl/react-native-gesture-handler),通过 “补丁化移植” 实现跨平台兼容(参考 360doc 个人图书馆方案); -
安装三方库后需检查
oh-package.json5配置,确保指定@rnoh/react-native-openharmony版本(如 0.72.53),避免版本冲突。
2、平台差异导致的组件不可用
报错如下:使用 RN 原生Slider组件设置训练难度(1~5 级)时,报错 “Element type is invalid: got undefined”,原因是Slider在 OpenHarmony 上实现不完整,运行时无法解析。
Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined.
Slider 组件在OpenHarmony上的实现不完整,导致运行时解析为 undefined
问题出在下列代码:
// 使用OpenHarmony未完全支持的Slider组件
import { Slider } from 'react-native';
// 渲染Slider
<Slider
style={styles.slider}
minimumValue={1}
maximumValue={5}
value={difficulty}
onValueChange={setDifficulty}
/>
我询问ai,并使用按钮组替代Slider,进行了如下更正:
<View style={styles.difficultyButtonsContainer}>
{[1, 2, 3, 4, 5].map((level) => (
<TouchableOpacity
key={level}
style={[styles.difficultyButton, difficulty === level && styles.difficultyButtonSelected]}
onPress={() => setDifficulty(level)}
>
<Text style={[styles.difficultyButtonText, difficulty === level && styles.difficultyButtonTextSelected]}>
{level}级
</Text>
</TouchableOpacity>
))}
</View>
3、异步操作未处理错误
出现如下问题:调用模拟 API 加载训练场景时,setLoading始终为true,界面卡住且无错误提示,原因是异步函数未捕获异常,导致setLoading(false)无法执行。
错误代码:
const fetchScenes = async () => {
setLoading(true);
await simulateApiDelay(1500); // 模拟网络请求
setScenes(mockScenes);
setLoading(false);
};
解决方案:
通过try-catch-finally完善错误处理,确保 “加载状态” 无论成功 / 失败都能正常关闭,同时添加错误提示
const fetchScenes = async () => {
try {
setLoading(true);
setError(null); // 重置错误状态
await simulateApiDelay(1500);
setScenes(mockScenes);
} catch (err) {
setError('加载失败,请重试'); // 显示错误信息
console.error('Failed to fetch scenes:', err);
} finally {
setLoading(false); // 无论成功失败都关闭加载状态
}
};
4、状态更新逻辑错误
实现上拉加载更多场景时,报错如下,
Warning: Cannot update a component's state while rendering a different component.
原因是直接修改useState返回的状态变量(loadingMore = true),未通过set函数更新,导致状态不触发重新渲染。直接修改 useState 返回的状态变量,而不是使用 set 函数,导致状态更新无效
// 错误:直接修改状态
const handleLoadMore = () => {
if (hasMore && !loadingMore) {
loadingMore = true; // 错误:直接赋值,不会触发重新渲染
fetchMoreScenes();
}
};
通过如下方式修改代码实现了改正:
import { useState } from 'react-native';
const LoadMoreScenes = () => {
const [hasMore, setHasMore] = useState(true); // 是否有更多数据
const [loadingMore, setLoadingMore] = useState(false); // 加载更多状态
const [scenes, setScenes] = useState([]);
// 加载更多逻辑
const fetchMoreScenes = async () => {
await simulateApiDelay(1000);
const newScenes = [/* 新场景数据 */];
setScenes(prev => [...prev, ...newScenes]); // 增量更新数据
setLoadingMore(false);
if (newScenes.length === 0) setHasMore(false); // 无更多数据时更新状态
};
// 处理上拉加载触发
const handleLoadMore = () => {
// 仅当“有更多数据”且“未在加载中”时触发
if (hasMore && !loadingMore) {
setLoadingMore(true); // 正确:使用set函数更新状态
fetchMoreScenes();
}
};
return (
<View>
{/* 场景列表 */}
{loadingMore && <Text>加载更多...</Text>}
{!hasMore && <Text>没有更多数据了</Text>}
{/* 上拉加载触发区域(如FlatList的onEndReached) */}
</View>
);
};
三、实现效果

选择场景

下拉刷新

上拉加载

训练入口:

1. 核心功能效果
| 功能模块 | 实现效果 |
|---|---|
| 下拉刷新 | 触发后显示蓝色加载指示器,刷新完成后更新场景列表数据 |
| 上拉加载 | 滑动到底部时加载更多场景,无数据时显示 “没有更多数据了” 提示 |
| 难度选择 | 5 个按钮对应 1~5 级难度,选中态高亮显示,点击可切换 |
| 实时数据展示 | 训练界面显示 “动作正确率(90%)”“运动范围(90°)”“心率(75 BPM)” 等数据 |
| 场景选择 | 支持医院康复中心(室内)、公园(户外)、个性化自定义场所 3 类训练环境选择 |
2. 当前系统局限(待优化)
-
未实现用户登录 / 登出功能,导致训练数据无法关联用户身份,无法持久化存储;
-
设备接入功能未完成,无法连接 VR 设备获取实时动作数据;
-
排行榜统计、AI 洞察分析等功能处于待开发状态,需后续补充接口与逻辑。
用户输入信息后才可进行数据反馈,登入/登出,目前无法完成训练数据收集、设备接入、排行榜统计等功能,系统后续仍在完善。
四、总结归纳
1、鸿蒙适配能力:掌握 RN 三方库鸿蒙适配方案(优先原生组件、使用补丁库)、平台差异组件替代策略,解决了库兼容性、组件不可用等核心问题;
2、状态管理规范:熟练使用useState(通过set函数更新)、useEffect(生命周期管理),结合try-catch-finally处理异步状态,避免界面卡死与报错;
3、用户体验优化:覆盖加载中、加载失败、空数据等全场景提示,通过按钮组、颜色区分等设计提升交互友好性;
4、模拟 API 与测试:实现 API 延迟模拟,便于测试不同加载状态下的界面表现,为后续对接真实接口打下基础;
5、代码结构化:将难度选择、场景加载等逻辑拆分为独立组件 / 函数,提升代码可维护性,符合模块化开发规范。
欢迎加入开源鸿蒙跨平台社区:
https://openharmonycrossplatform.csdn.net
更多推荐

所有评论(0)