欢迎大家加入开源鸿蒙跨平台开发者社区,一起共建开源鸿蒙跨平台生态。


在医疗健康领域,健康预警系统正成为慢性病管理的重要工具。今天我们将深入分析一个基于 React Native 开发的健康预警应用,探讨其技术实现细节以及在鸿蒙系统上的跨端适配策略。

Hooks 进行状态管理

该应用采用了 React Native 作为核心框架,结合 TypeScript 提供类型安全保障。从代码结构来看,项目遵循了 React 函数式组件的设计范式,充分利用了 Hooks 进行状态管理和副作用处理。

const HealthAlertApp: React.FC = () => {
  const [devices] = useState<Device[]>([...]);
  const [healthData, setHealthData] = useState<HealthData[]>([...]);
  const [alertNotifications, setAlertNotifications] = useState<AlertNotification[]>([...]);
  const [selectedDevice, setSelectedDevice] = useState<string | null>(null);
  const [isModalVisible, setIsModalVisible] = useState(false);
  const [modalContent, setModalContent] = useState('');
  
  // 自动检测异常数据并发送预警
  useEffect(() => {
    const abnormalData = healthData.filter(data => data.isAbnormal);
    if (abnormalData.length > 0) {
      const newAlert: AlertNotification = {
        id: (alertNotifications.length + 1).toString(),
        message: '检测到异常健康数据,请查看详细信息',
        timestamp: new Date().toLocaleString()
      };
      setAlertNotifications([...alertNotifications, newAlert]);
      Alert.alert('健康预警', '检测到异常健康数据,请及时处理');
    }
  }, [healthData]);
  // ...
};

这种函数式组件的写法不仅代码更简洁,而且在性能上也有优势。通过多个 useState 钩子,开发者可以独立管理不同的状态,如设备列表、健康数据、预警通知等。同时,使用 useEffect 钩子实现了自动检测异常数据并发送预警的功能,体现了 React 组件化和声明式编程的优势。

数据结构

项目使用 TypeScript 定义了清晰的数据结构,例如 DeviceHealthDataAlertNotification 类型:

type Device = {
  id: string;
  name: string;
  type: string;
  connected: boolean;
};

type HealthData = {
  id: string;
  date: string;
  bloodPressure: string;
  glucose: string;
  isAbnormal: boolean;
};

type AlertNotification = {
  id: string;
  message: string;
  timestamp: string;
};

这种类型定义为代码提供了良好的可维护性和类型检查,避免了运行时错误。在跨端开发中,类型系统的重要性更加凸显,因为不同平台的类型处理可能存在差异,TypeScript 可以帮助开发者在编译时就发现潜在问题。

响应式

应用采用了 Flexbox 布局系统,结合 Dimensions API 实现响应式设计:

const { width, height } = Dimensions.get('window');

这种方式确保了应用在不同屏幕尺寸的设备上都能良好显示。特别值得注意的是,代码中使用了 ScrollView 组件来处理内容滚动,对于设备列表、健康数据和预警通知等可能超出屏幕高度的内容,这种处理方式非常合适。

跨端适配

从代码中可以看出,开发者采用了一套通用的组件和 API,这些都是 React Native 提供的跨平台解决方案:

  • 使用 SafeAreaView 确保内容不会被设备刘海或底部安全区域遮挡
  • 使用 TouchableOpacity 实现跨平台的点击效果
  • 使用 Alert 实现跨平台的弹窗提示
  • 使用 Modal 实现跨平台的模态框
  • 使用 TextInput 实现跨平台的文本输入

这些组件在 iOS、Android 和鸿蒙系统上都能正常工作,体现了 React Native 的 “Write Once, Run Anywhere” 理念。


设备管理

应用实现了设备的连接和断开功能:

const handleConnectDevice = (deviceId: string) => {
  const device = devices.find(d => d.id === deviceId);
  if (device) {
    Alert.alert('设备连接', `${device.name} 已连接`);
  }
};

const handleDisconnectDevice = (deviceId: string) => {
  const device = devices.find(d => d.id === deviceId);
  if (device) {
    Alert.alert('设备断开', `${device.name} 已断开`);
  }
};

通过这种方式,用户可以方便地管理智能设备的连接状态,提升了用户体验。连接和断开操作通过 Alert 弹窗提供反馈,确保用户了解操作结果。

健康数据管理

应用实现了健康数据的查看功能:

const handleViewData = (dataId: string) => {
  const data = healthData.find(d => d.id === dataId);
  if (data) {
    setModalContent(`日期: ${data.date}\n血压: ${data.bloodPressure}\n血糖: ${data.glucose}\n状态: ${data.isAbnormal ? '异常' : '正常'}`);
    setIsModalVisible(true);
  }
};

通过这种方式,用户可以点击健康数据记录查看详细信息,提升了用户体验。详细信息通过模态框展示,避免了页面跳转,保持了操作的连续性。同时,应用通过不同的样式来标识异常数据,使得用户可以直观地识别异常情况。

预警通知管理

应用实现了预警通知的查看和清除功能:

const handleViewAlert = (alertId: string) => {
  const alert = alertNotifications.find(a => a.id === alertId);
  if (alert) {
    setModalContent(`预警信息: ${alert.message}\n时间: ${alert.timestamp}`);
    setIsModalVisible(true);
  }
};

const handleClearAlert = (alertId: string) => {
  setAlertNotifications(alertNotifications.filter(a => a.id !== alertId));
  Alert.alert('预警清除', '预警已清除');
};

这种设计使得用户可以方便地管理预警通知,提升了用户体验。预警通知的查看和清除操作都通过 Alert 弹窗提供反馈,确保用户了解操作结果。

自动异常检测

应用实现了自动检测异常数据并发送预警的功能:

useEffect(() => {
  const abnormalData = healthData.filter(data => data.isAbnormal);
  if (abnormalData.length > 0) {
    const newAlert: AlertNotification = {
      id: (alertNotifications.length + 1).toString(),
      message: '检测到异常健康数据,请查看详细信息',
      timestamp: new Date().toLocaleString()
    };
    setAlertNotifications([...alertNotifications, newAlert]);
    Alert.alert('健康预警', '检测到异常健康数据,请及时处理');
  }
}, [healthData]);

这种设计使得应用可以自动监测健康数据的异常情况,并及时通知用户,提升了用户体验。自动检测功能通过 useEffect 钩子实现,当健康数据发生变化时会自动触发检测。

模态框功能

应用使用 Modal 组件实现了模态框功能:

const openModal = (content: string) => {
  setModalContent(content);
  setIsModalVisible(true);
};

const closeModal = () => {
  setIsModalVisible(false);
};

这种方式可以在不离开当前页面的情况下展示额外信息,提升了用户体验。

应用通过样式和图标为用户提供了清晰的视觉反馈:

  • 使用不同的图标来区分设备、健康数据和预警通知
  • 使用不同的样式来标识异常数据
  • 使用 Alert 弹窗来确认用户的操作
  • 使用模态框来展示详细信息

这种设计使得用户可以直观地了解应用的状态和操作结果,提升了用户体验。


组件兼容性

在鸿蒙系统上,React Native 应用需要考虑组件的兼容性。从代码来看,开发者使用的都是 React Native 核心组件,这些组件在鸿蒙系统上都有对应的实现。例如:

  • View 对应鸿蒙的 Component
  • Text 对应鸿蒙的 Text
  • ScrollView 对应鸿蒙的 ListContainer
  • Modal 对应鸿蒙的 Dialog
  • TouchableOpacity 对应鸿蒙的 Button
  • TextInput 对应鸿蒙的 TextInput

鸿蒙系统对应用性能有较高要求,特别是在内存使用和启动速度方面。该应用的实现方式有利于在鸿蒙系统上获得良好的性能:

  • 使用函数式组件减少了内存占用
  • 使用多个 useState 钩子进行细粒度的状态管理
  • 使用 useEffect 钩子实现副作用的精确控制
  • 避免了复杂的计算和不必要的渲染
  • 使用 TouchableOpacity 替代 Button,减少了视图层级

虽然代码中没有直接调用原生能力,但在实际的鸿蒙适配中,可能需要通过 React Native 的 Native Modules 机制来调用鸿蒙的特有 API。例如,当需要实现真正的设备连接功能或推送通知功能时,可能需要调用鸿蒙的蓝牙 API 或通知 API。

资源加载

代码中使用了 Base64 编码的图标:

const ICONS_BASE64 = {
  device: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
  warning: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
  notification: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
  settings: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
};

这种方式的优点是减少了网络请求,提高了应用的加载速度。对于小型图标来说,Base64 编码是一种非常有效的优化策略,特别是在跨端开发中,可以避免不同平台对图片资源的处理差异。


模块化

应用采用了清晰的模块化设计:

  • 状态管理与 UI 渲染分离
  • 数据结构与业务逻辑分离
  • 样式与组件分离

这种设计使得代码结构清晰,易于维护和扩展。例如,当需要添加新的设备类型或健康数据类型时,只需要修改对应的数据结构和 UI 渲染逻辑即可,不需要修改整体架构。

TypeScript 的使用为代码提供了类型安全保障,减少了运行时错误的可能性。特别是在跨端开发中,类型系统可以帮助开发者发现不同平台之间的潜在差异。

应用使用了 StyleSheet.create 来管理样式,这种方式的优点是:

  • 提高了样式的复用性
  • 减少了运行时的样式计算
  • 使代码更加清晰易读

应用的代码组织合理,逻辑清晰:

  • 首先定义了必要的类型和数据
  • 然后实现了组件的状态管理
  • 接着实现了副作用处理逻辑
  • 然后实现了事件处理函数
  • 最后实现了 UI 渲染

这种组织方式使得代码易于阅读和理解,便于后续的维护和扩展。


通过对这个健康预警应用的技术分析,我们可以看到 React Native 在跨端开发中的优势:

  • 开发效率高:使用 JavaScript/TypeScript 开发,代码量少,开发周期短
  • 跨平台兼容性好:一套代码可以在 iOS、Android 和鸿蒙系统上运行
  • 性能表现优秀:通过原生组件渲染,性能接近原生应用
  • 生态系统成熟:拥有丰富的第三方库和工具
  • 用户体验良好:可以构建出与原生应用相媲美的界面和交互
  • 功能强大:通过 Hooks 等特性,可以实现复杂的业务逻辑

在鸿蒙系统逐渐普及的背景下,React Native 作为一种跨端解决方案,具有广阔的应用前景。开发者可以通过学习和掌握 React Native,快速构建支持多平台的医疗应用,提高开发效率和代码复用率。

同时,我们也可以看到,React Native 在构建具有实时监测和预警功能的应用时表现出色,例如这个健康预警应用。通过 useEffect 钩子和状态管理,开发者可以实现复杂的实时监测逻辑,为用户提供及时的健康预警服务。


健康预警是智慧医疗体系中风险防控的核心环节,聚焦“设备连接-数据采集-异常检测-预警推送”的全流程健康风险管理逻辑,既要保证血压、血糖等健康数据异常状态的实时检测与预警触发,又需兼顾多端交互体验的一致性与医疗预警信息展示的规范性。本文基于这套 React Native 健康预警应用代码,从架构设计、核心业务逻辑、鸿蒙跨端适配三个维度,系统解读健康预警场景的跨端开发逻辑与技术要点,重点剖析 React Native 与鸿蒙系统的适配底层逻辑和落地实践方案,尤其针对异常数据自动检测、预警通知生成、设备连接管理等核心交互的跨端实现进行深度拆解。

一、 React Native 原生基础组件(SafeAreaView、ScrollView、TouchableOpacity、Modal 等)

该健康预警应用基于 React Native 函数式组件 + TypeScript 强类型架构构建,核心依赖 React Native 原生基础组件(SafeAreaView、ScrollView、TouchableOpacity、Modal 等)与 Hooks 状态管理(useState/useEffect),未引入第三方 UI 框架或复杂状态管理库。这种极简架构是健康预警这类“强实时检测、轻数据计算”场景实现鸿蒙跨端的核心优势——轻量意味着适配成本更低,且能最大程度保证多端健康预警流程逻辑的一致性,尤其适合设备列表展示、异常数据检测、预警通知管理等核心逻辑的跨端复用。

从跨端技术底层逻辑来看,React Native 以“JS 桥接层(JS Bridge)”为核心实现跨端能力:前端编写的 JSX 组件与健康预警逻辑,通过桥接层映射为不同平台的原生组件,iOS 端映射为 UIKit 体系、Android 端映射为 View 体系,而鸿蒙(HarmonyOS)端则通过 React Native for HarmonyOS 适配层,完成 React Native 组件/API 与鸿蒙 ArkUI 组件/API 的双向映射。该应用的代码结构完全遵循跨端开发规范:无平台专属硬编码、状态管理基于 React 原生 Hooks、样式采用跨端通用的 Flex 布局,从根源上消除了鸿蒙适配的技术壁垒,同时保证设备连接/断开、异常数据检测、预警通知生成等核心健康预警流程逻辑在多端的一致性。

值得注意的是,应用新增的 useEffect 生命周期钩子实现异常数据自动检测逻辑,该钩子在鸿蒙端会被适配层映射为 ArkTS 的 @Watch 装饰器 + aboutToAppear 生命周期组合,保证数据变化监听的跨端一致性,这也是健康预警场景中“实时检测”核心能力跨端落地的关键技术基础。


1. 健康预警

应用通过 TypeScript 接口扩展定义了 Device(设备)、HealthData(健康数据)、AlertNotification(预警通知)三类核心数据类型,字段设计精准匹配健康预警全流程数据需求:

  • Device 涵盖设备ID、名称、类型、连接状态,延续了智能设备管理的基础数据结构,保证设备连接状态的跨端统一识别;
  • HealthData 在原有血压、血糖字段基础上新增 isAbnormal 异常状态标识,该布尔型字段是异常检测逻辑的核心依据,在鸿蒙端适配层可直接映射为 ArkTS 的 boolean 类型,避免多端数据类型解析差异导致的异常检测失效;
  • AlertNotification 新增预警ID、提示信息、时间戳字段,完整覆盖预警通知的展示与管理需求,时间戳字段采用通用字符串格式,保证跨端时间展示的一致性。

这种强类型+场景化的数据模型设计,在跨端场景下保证了数据结构的一致性——鸿蒙端适配层可直接解析 TypeScript 类型定义,与 ArkTS 中的数据模型形成精准映射,避免多端数据格式不一致导致的异常状态判断错误、预警通知展示异常等核心问题,尤其在异常数据标识、预警信息时间戳等关键医疗预警信息的传递上,保证了跨端的数据准确性。

2. Hooks 状态管理

应用在基础 useState 之上新增 useEffect 实现异常数据监听,核心状态均具备跨端复用的特性:

  • 基础数据状态(devices/healthData/alertNotifications)中,devices 仍为只读设计,适配层自动映射为鸿蒙的 @State 响应式状态;healthData 支持动态更新,其变化会触发 useEffect 执行异常检测,该逻辑在鸿蒙端会被适配层转换为 ArkTS 的状态监听逻辑,新增异常数据时可实时触发预警;alertNotifications 支持预警通知的新增与删除,其更新方法在鸿蒙端会被转换为 ArkTS 的状态更新逻辑,预警列表的实时刷新跨端一致;
  • 交互状态(selectedDevice/isModalVisible/modalContent)延续基础状态设计,鸿蒙端适配层可直接映射为 ArkTS 的 @State/@Link 状态,弹窗展示预警详情、数据详情的逻辑跨端统一;
  • 核心生命周期逻辑(useEffect)以 healthData 为依赖项,实现“数据变化-异常检测-预警生成-弹窗提示”的全流程自动化,该依赖监听逻辑在鸿蒙端会被适配层转换为 ArkTS 的 @Watch 装饰器,保证数据变化时异常检测逻辑的实时触发,且检测逻辑(filter 筛选异常数据)为纯 JS 数组操作,鸿蒙端直接执行,检测规则跨端一致。

1. 样式体系

应用在原有样式基础上新增异常数据、预警通知专属样式,核心样式设计仍遵循跨端兼容原则,适配鸿蒙系统无明显改造成本,且针对健康预警场景的样式特性做了深度优化:

  • Flex 布局的跨端统一:从设备卡片的“图标+信息+操作按钮”、健康数据卡片的“图标+数据+预警标识”,到预警通知卡片的“图标+信息+清除按钮”,全量采用 Flex 横向布局(flexDirection: 'row' + alignItems: 'center')。Flex 作为 W3C 标准布局方案,在鸿蒙端可被适配层直接解析为 ArkUI 的 Flex 布局,无需重构任何布局逻辑,仅需保证样式属性命名与 React Native 规范一致,尤其在异常数据卡片、预警通知卡片等核心预警展示区域的布局上,Flex 布局的跨端一致性表现突出;
  • 健康预警专属样式的跨端适配
    • 异常数据卡片的高亮样式(abnormalDataCardborderLeftWidth: 4 + borderLeftColor: '#ef4444')为通用边框属性,鸿蒙端适配层会将尺寸单位转换为 vp,红色左侧边框的视觉警示效果跨端统一,用户可快速识别异常健康数据;
    • 预警图标(warningIconfontSize: 20 + color: '#ef4444')为通用文本样式属性,鸿蒙端直接解析,⚠️ 图标与红色配色的警示组合跨端一致,符合医疗预警的视觉设计规范;
    • 预警通知卡片的背景色(#fee2e2)为通用颜色属性,鸿蒙端适配层转换为 ArkUI 的 Color 类型,浅红色背景的视觉提示效果跨端统一,与异常数据卡片形成视觉联动;
    • 清除按钮的样式(clearButton:背景色 #ef4444、圆角 8)与断开按钮样式统一,鸿蒙端可直接复用样式解析逻辑,按钮的点击区域与视觉效果跨端一致;
  • 屏幕适配与层级兼容Dimensions.get('window') 获取设备宽高的 API 在鸿蒙端已完成原生映射,为不同尺寸鸿蒙设备(手机、平板)的自适应布局预留基础;shadow + elevation 的双层阴影设计,鸿蒙系统对 elevation 属性的支持与 Android 端完全兼容,保证设备卡片、预警卡片等组件的视觉层级跨端统一;
  • 安全区域适配SafeAreaView 组件在鸿蒙端已适配为 ArkUI 的 SafeArea 组件,保证头部健康预警标题区域在不同鸿蒙设备上的展示完整性,避免标题被刘海屏、全面屏遮挡。

(1)异常数据展示组件

异常数据展示组件是健康预警的核心视觉环节,核心适配逻辑如下:

  • 健康数据卡片的条件样式渲染(data.isAbnormal && styles.abnormalDataCard)为纯 JS 条件判断,鸿蒙端直接执行,异常数据卡片的红色左侧边框、预警图标展示状态与 isAbnormal 字段精准匹配,跨端一致;
  • 预警图标(warningIcon)的条件渲染逻辑(data.isAbnormal && <Text style={styles.warningIcon}>⚠️</Text>)为基础 JSX 条件渲染,鸿蒙端适配层会将其转换为 ArkTS 的 if 条件渲染,图标展示逻辑跨端统一;
  • 数据卡片的点击逻辑(handleViewData)新增异常状态展示(状态: ${data.isAbnormal ? '异常' : '正常'}),该字符串拼接逻辑为纯 JS 操作,鸿蒙端直接执行,弹窗内异常状态的展示格式跨端一致。
(2)预警通知管理组件

预警通知管理组件是健康预警的核心交互环节,核心适配逻辑如下:

  • 预警通知列表的渲染采用 map 方法遍历 alertNotifications 数组,该逻辑为纯 JS 数组操作,鸿蒙端通过 JS 引擎直接执行,预警列表的渲染顺序与展示内容跨端一致,保证预警信息按生成时间排序展示的核心逻辑不被破坏;
  • 预警详情查看逻辑(handleViewAlert)包含预警查找、弹窗内容拼接、弹窗显隐状态更新,预警查找(alertNotifications.find(a => a.id === alertId))为 JS 原生数组方法,弹窗内容拼接包含预警信息与时间戳,该逻辑在鸿蒙端直接执行,预警详情的展示格式跨端统一;
  • 预警清除逻辑(handleClearAlert)采用数组 filter 方法删除指定预警,该操作符为 ES6 标准语法,鸿蒙端直接执行,清除后的预警列表实时刷新,且清除后的弹窗反馈(Alert.alert)会被适配层转换为鸿蒙的 AlertDialog 组件,提示内容与交互逻辑跨端一致。
(3)自动预警触发组件

自动预警触发组件是健康预警的核心能力环节,核心适配逻辑如下:

  • useEffect 监听 healthData 变化的逻辑,在鸿蒙端会被适配层转换为 ArkTS 的 @Watch 装饰器,数据更新时自动执行异常检测,监听触发时机跨端一致;
  • 异常数据筛选逻辑(healthData.filter(data => data.isAbnormal))为纯 JS 数组方法,鸿蒙端直接执行,异常数据的筛选规则(isAbnormal === true)跨端一致,保证只有异常数据才会触发预警;
  • 新预警生成逻辑(newAlert)包含 ID 生成、信息拼接、时间戳格式化(new Date().toLocaleString()),时间戳格式化为 JS 原生 API,鸿蒙端直接执行,生成的预警时间格式跨端统一;
  • 预警生成后的弹窗提示(Alert.alert('健康预警', '检测到异常健康数据,请及时处理'))使用跨端兼容的 Alert.alert API,鸿蒙端适配层转换为 AlertDialog 组件,预警提示的内容与交互逻辑跨端一致。

1. 异常数据自动检测

useEffect 驱动的异常检测逻辑是健康预警的核心业务能力,实现了“数据监听-异常筛选-预警生成-弹窗提示”的全流程自动化,核心适配逻辑如下:

  • 依赖监听逻辑(useEffect(() => {}, [healthData]))在鸿蒙端会被适配层转换为 ArkTS 的 @Watch 装饰器,healthData 状态更新时自动触发检测,监听机制跨端一致,保证异常数据的实时检测;
  • 异常筛选逻辑(healthData.filter(data => data.isAbnormal))为纯 JS 数组操作,鸿蒙端直接执行,筛选规则仅依赖 isAbnormal 布尔字段,跨端无差异,保证异常数据识别的准确性;
  • 新预警生成逻辑中,时间戳格式化(new Date().toLocaleString())为 JS 原生 Date API,鸿蒙端通过 JS 引擎直接执行,生成的本地时间格式跨端统一,保证预警通知时间的准确性;
  • 预警列表更新逻辑(setAlertNotifications([...alertNotifications, newAlert]))采用数组扩展运算符,该操作符为 ES6 标准语法,鸿蒙端直接执行,预警列表的实时刷新跨端一致;
  • 弹窗提示逻辑使用跨端兼容的 Alert.alert API,鸿蒙端适配层处理弹窗转换,提示内容为固定字符串,跨端展示与交互逻辑完全一致,保证用户能及时收到异常预警。

2. 设备连接/断开逻辑

handleConnectDevice/handleDisconnectDevice 函数延续智能设备管理的核心操作逻辑,核心适配逻辑如下:

  • 设备查找逻辑(devices.find(d => d.id === deviceId))为纯 JS 数组方法调用,鸿蒙端直接执行,基于 ID 精准查找设备的规则跨端一致;
  • 反馈提示逻辑(Alert.alert)使用跨端兼容的弹窗 API,鸿蒙端转换为 AlertDialog 组件,提示内容的拼接逻辑(${device.name} 已连接/已断开)为纯 JS 字符串操作,跨端一致;
  • 生产环境中若需对接真实的设备蓝牙/网络连接逻辑,扩展的连接/断开代码(如调用蓝牙 API)为纯 JS 原生模块调用,鸿蒙端适配层已完成对蓝牙等原生能力的封装,核心触发逻辑无需修改,仅需适配鸿蒙的设备权限申请逻辑即可。

3. 预警通知管理逻辑

handleViewAlert/handleClearAlert 函数是预警通知管理的核心交互逻辑,核心适配逻辑如下:

  • 预警查看逻辑(handleViewAlert)包含预警查找、弹窗内容拼接,预警查找为 JS 原生数组方法,弹窗内容拼接包含预警信息与时间戳,该逻辑在鸿蒙端直接执行,预警详情的展示格式跨端统一;
  • 预警清除逻辑(handleClearAlert)采用 filter 方法删除指定预警,该数组操作在鸿蒙端直接执行,清除后的预警列表实时刷新,且清除反馈的弹窗提示跨端一致;
  • 生产环境中若需扩展预警批量清除、已读标记等功能,新增逻辑均为纯 JS 数组操作,鸿蒙端可直接复用,仅需新增对应的 UI 交互组件即可,核心数据处理逻辑无需适配。

4. 跨端 API

应用使用的核心 API 均为 React Native 跨端兼容 API,在鸿蒙端可无缝适配:

  • 数组 API:map/find/filter/扩展运算符等数组方法为 JS 原生 API,鸿蒙端通过 JS 引擎直接执行,无需适配,保证设备/健康数据/预警列表的渲染、筛选、更新等核心逻辑的跨端一致性;
  • 日期 API:new Date()/toLocaleString() 等日期操作 API 为 JS 原生 API,鸿蒙端直接执行,保证预警时间戳格式的跨端统一;
  • 生命周期 API:useEffect 钩子在鸿蒙端被适配层转换为 ArkTS 的状态监听逻辑,依赖项触发机制跨端一致,保证异常检测的实时性;
  • 弹窗 API:Alert.alert/Modal 已被适配层封装为鸿蒙的 AlertDialog/Dialog 组件,交互逻辑完全复用,在预警提示、设备操作反馈、详情展示等核心场景中,弹窗的展示与操作逻辑多端统一;
  • 样式 API:StyleSheet.create 封装的样式规则,适配层转换为 ArkUI 的样式对象,新增的异常数据、预警通知样式属性(borderLeftWidth/backgroundColor)均为通用属性,无需修改即可适配鸿蒙。

该健康预警应用作为智慧医疗风险防控核心模块,适配鸿蒙系统的成本极低,核心适配思路与技术要点如下:

1. 生命周期

应用核心的 useEffect 异常检测逻辑,在鸿蒙端通过 React Native for HarmonyOS 适配层转换为 ArkTS 的 @Watch 装饰器 + @State 状态组合,无需修改原有代码即可实现状态监听的跨端一致。例如:

// 鸿蒙端 ArkTS 等效逻辑(适配层自动转换)
@Component
struct HealthAlertComponent {
  @State healthData: HealthData[] = [...];
  @State alertNotifications: AlertNotification[] = [...];

  @Watch('onHealthDataChange')
  setHealthData(newData: HealthData[]) {
    this.healthData = newData;
  }

  onHealthDataChange() {
    const abnormalData = this.healthData.filter(data => data.isAbnormal);
    if (abnormalData.length > 0) {
      // 预警生成逻辑
    }
  }
}

这种自动转换机制保证了 useEffect 核心逻辑的跨端复用,无需手动适配鸿蒙的生命周期体系。

2. 性能

该应用当前的列表渲染采用基础 map 方法,在生产环境中若预警通知/健康数据量较大(如超过50条),可替换为 React Native 的 FlatList 高性能列表组件——FlatList 在鸿蒙端已完成深度适配,支持虚拟化列表渲染,其核心属性(data/renderItem/keyExtractor)与 React Native 端完全一致,仅需少量调整即可适配鸿蒙端的性能优化策略,保证预警列表、健康数据列表的滚动性能,尤其适合长期监测产生的海量健康数据与预警信息展示场景。

3. 健康预警样式

鸿蒙系统有自身的设计规范,在适配时可通过条件编译实现差异化样式,既保证遵循鸿蒙设计规范,又能最大程度复用现有代码:

// 鸿蒙端健康预警样式差异化适配示例
import { Platform } from 'react-native';
const isHarmonyOS = Platform.OS === 'harmony';

const adaptiveStyles = {
  abnormalDataCard: {
    ...styles.abnormalDataCard,
    borderLeftColor: isHarmonyOS ? '#dc2626' : '#ef4444',
    borderLeftWidth: isHarmonyOS ? 5 : 4,
  },
  alertCard: {
    ...styles.alertCard,
    backgroundColor: isHarmonyOS ? '#fecdd3' : '#fee2e2',
    borderRadius: isHarmonyOS ? 14 : 12,
  },
  clearButton: {
    ...styles.clearButton,
    backgroundColor: isHarmonyOS ? '#dc2626' : '#ef4444',
    borderRadius: isHarmonyOS ? 10 : 8,
  }
};

这种轻量级的差异化适配,既能保证符合鸿蒙的设计规范,又能保留现有代码的完整性,尤其在异常数据卡片、预警通知卡片、清除按钮等核心预警交互组件的样式适配中,效果显著。

该 React Native 健康预警应用实现了设备管理、异常数据自动检测、预警通知生成与管理等核心智慧医疗风险防控功能,代码结构符合跨端开发规范,可低成本适配鸿蒙系统。针对生产环境落地,可做以下优化:

  1. 异常检测规则增强:扩展 useEffect 中的异常检测逻辑,添加血压(如收缩压>140/舒张压>90)、血糖(如空腹>7.0)的数值范围校验,校验规则为纯 JS 逻辑,鸿蒙端可直接执行,避免仅依赖 isAbnormal 字段导致的检测规则单一问题,提升异常检测的准确性;
  2. 预警推送能力扩展:对接鸿蒙的推送服务(Push Kit),替换当前的本地弹窗提示,实现异常数据的系统级推送,鸿蒙端适配时仅需封装推送服务的原生 API,核心异常检测逻辑无需重构,保证预警信息的触达率;
  3. 数据持久化与同步:引入 AsyncStorage(或鸿蒙原生 Preferences)实现健康数据与预警通知的本地加密存储,同时对接医疗云平台接口实现数据云端同步,鸿蒙端兼容主流存储方案,可直接复用数据处理逻辑,保证健康预警数据的跨设备同步;
  4. 错误边界与异常处理:添加 React Error Boundary 捕获运行时错误(如异常检测逻辑异常、预警生成失败),避免应用崩溃,鸿蒙端可通过适配层将错误信息同步到原生错误日志系统,便于健康预警应用的线上问题排查,同时保证预警触发失败时的用户友好提示;
  5. 鸿蒙原生能力融合:通过 React Native 原生模块封装鸿蒙的健康服务能力,将异常健康数据接入鸿蒙的健康应用,实现预警信息的统一管理,核心异常检测逻辑可完全复用现有代码,仅需对接鸿蒙的健康服务接口。

真实演示案例代码:








// App.tsx
import React, { useState, useEffect } from 'react';
import { SafeAreaView, View, Text, StyleSheet, TouchableOpacity, ScrollView, Dimensions, Alert, TextInput, Modal } from 'react-native';

// Base64 图标库
const ICONS_BASE64 = {
  device: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
  warning: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
  notification: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
  settings: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
};

const { width, height } = Dimensions.get('window');

// 设备类型
type Device = {
  id: string;
  name: string;
  type: string;
  connected: boolean;
};

// 健康数据类型
type HealthData = {
  id: string;
  date: string;
  bloodPressure: string;
  glucose: string;
  isAbnormal: boolean;
};

// 预警通知类型
type AlertNotification = {
  id: string;
  message: string;
  timestamp: string;
};

// 健康预警应用组件
const HealthAlertApp: React.FC = () => {
  const [devices] = useState<Device[]>([
    {
      id: '1',
      name: '血压计',
      type: '血压监测',
      connected: true
    },
    {
      id: '2',
      name: '血糖仪',
      type: '血糖监测',
      connected: false
    }
  ]);

  const [healthData, setHealthData] = useState<HealthData[]>([
    {
      id: '1',
      date: '2023-12-01',
      bloodPressure: '120/80',
      glucose: '5.6',
      isAbnormal: false
    },
    {
      id: '2',
      date: '2023-12-02',
      bloodPressure: '140/90',
      glucose: '7.2',
      isAbnormal: true
    }
  ]);

  const [alertNotifications, setAlertNotifications] = useState<AlertNotification[]>([
    {
      id: '1',
      message: '血压异常,请及时就医',
      timestamp: '2023-12-02 10:00'
    }
  ]);

  const [selectedDevice, setSelectedDevice] = useState<string | null>(null);
  const [isModalVisible, setIsModalVisible] = useState(false);
  const [modalContent, setModalContent] = useState('');

  // 自动检测异常数据并发送预警
  useEffect(() => {
    const abnormalData = healthData.filter(data => data.isAbnormal);
    if (abnormalData.length > 0) {
      const newAlert: AlertNotification = {
        id: (alertNotifications.length + 1).toString(),
        message: '检测到异常健康数据,请查看详细信息',
        timestamp: new Date().toLocaleString()
      };
      setAlertNotifications([...alertNotifications, newAlert]);
      Alert.alert('健康预警', '检测到异常健康数据,请及时处理');
    }
  }, [healthData]);

  const handleConnectDevice = (deviceId: string) => {
    const device = devices.find(d => d.id === deviceId);
    if (device) {
      Alert.alert('设备连接', `${device.name} 已连接`);
    }
  };

  const handleDisconnectDevice = (deviceId: string) => {
    const device = devices.find(d => d.id === deviceId);
    if (device) {
      Alert.alert('设备断开', `${device.name} 已断开`);
    }
  };

  const handleViewData = (dataId: string) => {
    const data = healthData.find(d => d.id === dataId);
    if (data) {
      setModalContent(`日期: ${data.date}\n血压: ${data.bloodPressure}\n血糖: ${data.glucose}\n状态: ${data.isAbnormal ? '异常' : '正常'}`);
      setIsModalVisible(true);
    }
  };

  const handleViewAlert = (alertId: string) => {
    const alert = alertNotifications.find(a => a.id === alertId);
    if (alert) {
      setModalContent(`预警信息: ${alert.message}\n时间: ${alert.timestamp}`);
      setIsModalVisible(true);
    }
  };

  const handleClearAlert = (alertId: string) => {
    setAlertNotifications(alertNotifications.filter(a => a.id !== alertId));
    Alert.alert('预警清除', '预警已清除');
  };

  const openModal = (content: string) => {
    setModalContent(content);
    setIsModalVisible(true);
  };

  const closeModal = () => {
    setIsModalVisible(false);
  };

  return (
    <SafeAreaView style={styles.container}>
      {/* 头部 */}
      <View style={styles.header}>
        <Text style={styles.title}>健康预警</Text>
        <Text style={styles.subtitle}>自动检测异常数据,及时发送预警通知</Text>
      </View>

      <ScrollView style={styles.content}>
        {/* 设备列表 */}
        <View style={styles.section}>
          <Text style={styles.sectionTitle}>设备列表</Text>
          {devices.map(device => (
            <View key={device.id} style={styles.deviceCard}>
              <Text style={styles.icon}>📱</Text>
              <View style={styles.cardInfo}>
                <Text style={styles.cardTitle}>{device.name}</Text>
                <Text style={styles.cardDescription}>{device.type}</Text>
              </View>
              <View style={styles.deviceActions}>
                {device.connected ? (
                  <TouchableOpacity 
                    style={styles.disconnectButton}
                    onPress={() => handleDisconnectDevice(device.id)}
                  >
                    <Text style={styles.disconnectText}>断开</Text>
                  </TouchableOpacity>
                ) : (
                  <TouchableOpacity 
                    style={styles.connectButton}
                    onPress={() => handleConnectDevice(device.id)}
                  >
                    <Text style={styles.connectText}>连接</Text>
                  </TouchableOpacity>
                )}
              </View>
            </View>
          ))}
        </View>

        {/* 健康数据 */}
        <View style={styles.section}>
          <Text style={styles.sectionTitle}>健康数据</Text>
          {healthData.map(data => (
            <TouchableOpacity 
              key={data.id}
              style={[
                styles.dataCard,
                data.isAbnormal && styles.abnormalDataCard
              ]}
              onPress={() => handleViewData(data.id)}
            >
              <Text style={styles.icon}>📊</Text>
              <View style={styles.cardInfo}>
                <Text style={styles.cardTitle}>{data.date}</Text>
                <Text style={styles.cardDescription}>血压: {data.bloodPressure}</Text>
                <Text style={styles.cardDescription}>血糖: {data.glucose}</Text>
              </View>
              {data.isAbnormal && (
                <Text style={styles.warningIcon}>⚠️</Text>
              )}
            </TouchableOpacity>
          ))}
        </View>

        {/* 预警通知 */}
        <View style={styles.section}>
          <Text style={styles.sectionTitle}>预警通知</Text>
          {alertNotifications.map(alert => (
            <View key={alert.id} style={styles.alertCard}>
              <Text style={styles.icon}>🔔</Text>
              <View style={styles.cardInfo}>
                <Text style={styles.cardTitle}>{alert.message}</Text>
                <Text style={styles.cardDescription}>{alert.timestamp}</Text>
              </View>
              <TouchableOpacity 
                style={styles.clearButton}
                onPress={() => handleClearAlert(alert.id)}
              >
                <Text style={styles.clearText}>清除</Text>
              </TouchableOpacity>
            </View>
          ))}
        </View>

        {/* 使用说明 */}
        <View style={styles.infoCard}>
          <Text style={styles.sectionTitle}>📘 使用说明</Text>
          <Text style={styles.infoText}>• 连接智能设备以自动采集数据</Text>
          <Text style={styles.infoText}>• 系统自动检测异常健康数据</Text>
          <Text style={styles.infoText}>• 异常数据将触发预警通知</Text>
          <Text style={styles.infoText}>• 及时处理预警信息,保障健康</Text>
        </View>

        {/* 弹框内容 */}
        <Modal
          animationType="slide"
          transparent={true}
          visible={isModalVisible}
          onRequestClose={closeModal}
        >
          <View style={styles.modalContainer}>
            <View style={styles.modalContent}>
              <Text style={styles.modalTitle}>详细信息</Text>
              <Text style={styles.modalText}>{modalContent}</Text>
              <TouchableOpacity
                style={styles.closeButton}
                onPress={closeModal}
              >
                <Text style={styles.closeButtonText}>关闭</Text>
              </TouchableOpacity>
            </View>
          </View>
        </Modal>
      </ScrollView>
    </SafeAreaView>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#f0f9ff',
  },
  header: {
    flexDirection: 'column',
    padding: 16,
    backgroundColor: '#ffffff',
    borderBottomWidth: 1,
    borderBottomColor: '#bae6fd',
  },
  title: {
    fontSize: 20,
    fontWeight: 'bold',
    color: '#0c4a6e',
    marginBottom: 4,
  },
  subtitle: {
    fontSize: 14,
    color: '#0284c7',
  },
  content: {
    flex: 1,
    marginTop: 12,
  },
  section: {
    backgroundColor: '#ffffff',
    marginHorizontal: 16,
    marginBottom: 12,
    borderRadius: 12,
    padding: 16,
    elevation: 2,
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 2 },
    shadowOpacity: 0.1,
    shadowRadius: 4,
  },
  sectionTitle: {
    fontSize: 16,
    fontWeight: '600',
    color: '#0c4a6e',
    marginBottom: 12,
  },
  deviceCard: {
    flexDirection: 'row',
    alignItems: 'center',
    backgroundColor: '#f0f9ff',
    borderRadius: 12,
    padding: 16,
    marginBottom: 12,
  },
  icon: {
    fontSize: 28,
    marginRight: 12,
  },
  cardInfo: {
    flex: 1,
  },
  cardTitle: {
    fontSize: 16,
    fontWeight: '500',
    color: '#0c4a6e',
    marginBottom: 4,
  },
  cardDescription: {
    fontSize: 14,
    color: '#0284c7',
    marginBottom: 2,
  },
  deviceActions: {
    flexDirection: 'row',
  },
  connectButton: {
    backgroundColor: '#10b981',
    paddingHorizontal: 12,
    paddingVertical: 6,
    borderRadius: 8,
  },
  connectText: {
    color: '#ffffff',
    fontSize: 12,
    fontWeight: '500',
  },
  disconnectButton: {
    backgroundColor: '#ef4444',
    paddingHorizontal: 12,
    paddingVertical: 6,
    borderRadius: 8,
  },
  disconnectText: {
    color: '#ffffff',
    fontSize: 12,
    fontWeight: '500',
  },
  dataCard: {
    flexDirection: 'row',
    alignItems: 'center',
    backgroundColor: '#f0f9ff',
    borderRadius: 12,
    padding: 16,
    marginBottom: 12,
  },
  abnormalDataCard: {
    borderLeftWidth: 4,
    borderLeftColor: '#ef4444',
  },
  warningIcon: {
    fontSize: 20,
    color: '#ef4444',
  },
  alertCard: {
    flexDirection: 'row',
    alignItems: 'center',
    backgroundColor: '#fee2e2',
    borderRadius: 12,
    padding: 16,
    marginBottom: 12,
  },
  clearButton: {
    backgroundColor: '#ef4444',
    paddingHorizontal: 12,
    paddingVertical: 6,
    borderRadius: 8,
  },
  clearText: {
    color: '#ffffff',
    fontSize: 12,
    fontWeight: '500',
  },
  infoCard: {
    backgroundColor: '#ffffff',
    marginHorizontal: 16,
    marginBottom: 80,
    borderRadius: 12,
    padding: 16,
    elevation: 2,
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 2 },
    shadowOpacity: 0.1,
    shadowRadius: 4,
  },
  infoText: {
    fontSize: 14,
    color: '#64748b',
    lineHeight: 20,
    marginBottom: 4,
  },
  modalContainer: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: 'rgba(0, 0, 0, 0.5)',
  },
  modalContent: {
    width: '80%',
    backgroundColor: '#ffffff',
    borderRadius: 12,
    padding: 20,
    elevation: 5,
  },
  modalTitle: {
    fontSize: 18,
    fontWeight: 'bold',
    color: '#0c4a6e',
    marginBottom: 12,
    textAlign: 'center',
  },
  modalText: {
    fontSize: 14,
    color: '#0c4a6e',
    lineHeight: 20,
    marginBottom: 20,
  },
  closeButton: {
    backgroundColor: '#0284c7',
    padding: 10,
    borderRadius: 8,
    alignItems: 'center',
  },
  closeButtonText: {
    color: '#ffffff',
    fontSize: 14,
    fontWeight: '500',
  },
});

export default HealthAlertApp;

请添加图片描述


打包

接下来通过打包命令npn run harmony将reactNative的代码打包成为bundle,这样可以进行在开源鸿蒙OpenHarmony中进行使用。

在这里插入图片描述

打包之后再将打包后的鸿蒙OpenHarmony文件拷贝到鸿蒙的DevEco-Studio工程目录去:

在这里插入图片描述

最后运行效果图如下显示:

请添加图片描述
本文介绍了一个基于React Native开发的健康预警应用的技术实现细节。该应用采用函数式组件设计,利用Hooks进行状态管理,通过TypeScript确保类型安全。文章重点分析了应用的数据结构设计、响应式布局实现以及跨平台适配策略,展示了如何利用React Native核心组件在鸿蒙系统上实现健康数据监测、异常预警和设备管理等功能。应用通过自动异常检测、模态框展示等交互设计提升了用户体验,体现了React Native在医疗健康领域的跨平台开发优势。

欢迎大家加入开源鸿蒙跨平台开发者社区,一起共建开源鸿蒙跨平台生态。

Logo

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

更多推荐