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


在医疗健康领域,晚期患者关怀正成为提升患者生命质量的重要组成部分。今天我们将深入分析一个基于 React Native 开发的晚期患者关怀应用,探讨其技术实现细节以及在鸿蒙系统上的跨端适配策略。

各个功能模块相对独立

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

const EndOfLifeCareApp: React.FC = () => {
  const [symptoms, setSymptoms] = useState<Symptom[]>([...]);
  const [counselings] = useState<Counseling[]>([...]);
  const [wishes, setWishes] = useState<Wish[]>([...]);
  const [spiritualResources] = useState<SpiritualResource[]>([...]);
  const [newSymptom, setNewSymptom] = useState({
    name: '',
    severity: '',
    description: ''
  });
  const [newWish, setNewWish] = useState({
    patientName: '',
    wishText: ''
  });
  const [isModalVisible, setIsModalVisible] = useState(false);
  const [modalContent, setModalContent] = useState('');
  // ...
};

这种函数式组件的写法不仅代码更简洁,而且在性能上也有优势。通过多个 useState 钩子,开发者可以独立管理不同的状态,如症状列表、心理疏导内容、心愿记录、灵性关怀资源以及用户输入等。这种状态管理方式对于晚期患者关怀应用来说非常合适,因为各个功能模块相对独立,同时又需要保持整体数据的一致性。

减少因类型错误导致的功能异常

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

type Symptom = {
  id: string;
  name: string;
  severity: string;
  description: string;
};

type Counseling = {
  id: string;
  title: string;
  content: string;
  therapist: string;
};

type Wish = {
  id: string;
  patientName: string;
  wishText: string;
  date: string;
};

type SpiritualResource = {
  id: string;
  title: string;
  description: string;
  link: string;
};

这种类型定义为代码提供了良好的可维护性和类型检查,避免了运行时错误。在跨端开发中,类型系统的重要性更加凸显,因为不同平台的类型处理可能存在差异,TypeScript 可以帮助开发者在编译时就发现潜在问题。特别是对于晚期患者关怀这类敏感应用,类型安全尤为重要,可以减少因类型错误导致的功能异常。

使用了 inputRow 样式来实现输入框的并排布局

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

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

这种方式确保了应用在不同屏幕尺寸的设备上都能良好显示。特别值得注意的是,代码中使用了 ScrollView 组件来处理内容滚动,对于症状列表、心理疏导内容和灵性关怀资源等可能超出屏幕高度的内容,这种处理方式非常合适。同时,应用使用了 inputRow 样式来实现输入框的并排布局,提升了空间利用率。

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

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

这些组件在 iOS、Android 和鸿蒙系统上都有对应的实现,体现了 React Native 的 “Write Once, Run Anywhere” 理念。


症状管理

应用实现了症状的添加和管理功能:

const handleAddSymptom = () => {
  if (newSymptom.name && newSymptom.severity && newSymptom.description) {
    const newSymptomEntry: Symptom = {
      id: (symptoms.length + 1).toString(),
      name: newSymptom.name,
      severity: newSymptom.severity,
      description: newSymptom.description
    };
    setSymptoms([...symptoms, newSymptomEntry]);
    setNewSymptom({ name: '', severity: '', description: '' });
    Alert.alert('添加成功', '症状已添加到管理列表中');
  } else {
    Alert.alert('提示', '请填写完整的症状信息');
  }
};

通过这种方式,医护人员可以方便地记录和管理患者的症状,提升了用户体验。添加症状时,应用会进行非空验证,确保不会添加不完整的症状信息。添加成功后,应用会清空输入框并提供反馈,确保医护人员了解操作结果。

心愿记录

应用实现了患者心愿的添加和管理功能:

const handleAddWish = () => {
  if (newWish.patientName && newWish.wishText) {
    const newWishEntry: Wish = {
      id: (wishes.length + 1).toString(),
      patientName: newWish.patientName,
      wishText: newWish.wishText,
      date: new Date().toISOString().split('T')[0]
    };
    setWishes([...wishes, newWishEntry]);
    setNewWish({ patientName: '', wishText: '' });
    Alert.alert('添加成功', '心愿已添加到记录中');
  } else {
    Alert.alert('提示', '请填写完整的心愿信息');
  }
};

这种设计使得医护人员可以帮助患者记录心愿,提升了患者的心理舒适度。添加心愿时,应用会自动记录当前日期,确保心愿记录的完整性。

心理疏导

应用实现了心理疏导内容和灵性关怀资源的查看功能:

const handleViewCounseling = (counselingId: string) => {
  const counseling = counselings.find(c => c.id === counselingId);
  if (counseling) {
    setModalContent(`标题: ${counseling.title}\n内容: ${counseling.content}\n心理咨询师: ${counseling.therapist}`);
    setIsModalVisible(true);
  }
};

const handleViewResource = (resourceId: string) => {
  const resource = spiritualResources.find(r => r.id === resourceId);
  if (resource) {
    setModalContent(`标题: ${resource.title}\n描述: ${resource.description}\n链接: ${resource.link}`);
    setIsModalVisible(true);
  }
};

通过这种方式,用户可以查看心理疏导内容和灵性关怀资源,提升了用户体验。详细信息通过模态框展示,避免了页面跳转,保持了操作的连续性。

模态框

应用使用 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 钩子进行细粒度的状态管理
  • 避免了复杂的计算和不必要的渲染
  • 使用 TouchableOpacity 替代 Button,减少了视图层级

虽然代码中没有直接调用原生能力,但在实际的鸿蒙适配中,可能需要通过 React Native 的 Native Modules 机制来调用鸿蒙的特有 API。例如,当需要实现与系统日历集成或发送通知时,可能需要调用鸿蒙的日历 API 或通知 API。

资源加载

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

const ICONS_BASE64 = {
  symptom: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
  counseling: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
  wish: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
  resources: '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 在构建具有复杂业务逻辑的应用时表现出色,例如这个晚期患者关怀应用。通过简单的状态管理和组件组合,开发者可以实现完整的症状管理、心理疏导、心愿记录和灵性关怀资源管理流程,为用户提供全方位的晚期患者关怀服务。


晚期患者关怀是智慧医疗中极具人文属性的核心场景,聚焦“症状管理-心理疏导-心愿记录-灵性关怀”全流程的临终关怀服务逻辑,既要保证症状严重程度、心愿内容等核心信息记录的准确性,又需兼顾多端操作的易用性与人文关怀场景下交互的温和性。本文基于这套 React Native 晚期患者关怀应用代码,从架构设计、核心业务逻辑、鸿蒙跨端适配三个维度,系统解读临终关怀场景的跨端开发逻辑与技术要点,重点剖析 React Native 与鸿蒙系统的适配底层逻辑和落地实践方案,尤其针对症状添加、心愿记录、关怀资源查看等核心交互的跨端实现进行深度拆解。

一、保证症状/心愿新增规则在多端的完全一致

该晚期患者关怀应用基于 React Native 函数式组件 + TypeScript 强类型架构构建,核心依赖 React Native 原生基础组件(SafeAreaView、ScrollView、TouchableOpacity、TextInput、Modal 等)与 useState 状态管理,未引入第三方 UI 框架或复杂状态管理库。这种极简架构是临终关怀这类“强信息记录、轻实时计算”场景实现鸿蒙跨端的核心优势——轻量意味着适配成本更低,且能最大程度保证多端关怀服务流程逻辑的一致性,尤其适合症状信息录入、心愿记录、关怀资源展示等核心逻辑的跨端复用。

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

值得注意的是,应用核心的症状添加(handleAddSymptom)与心愿记录(handleAddWish)逻辑均为纯 JS 数组操作与状态更新实现,无任何平台相关依赖,这是跨端复用的关键——鸿蒙端可通过 JS 引擎直接执行该逻辑,无需适配任何原生能力,保证症状/心愿新增规则在多端的完全一致,避免因平台差异导致的关怀数据记录错误。


1. 晚期患者关怀

应用通过 TypeScript 接口定义了 Symptom(症状)、Counseling(心理疏导)、Wish(心愿)、SpiritualResource(灵性关怀资源)四类核心数据类型,字段设计精准匹配晚期患者关怀全流程数据需求:

  • Symptom 涵盖症状ID、名称、严重程度、描述,所有字段均为 JS 基础数据类型(string),在鸿蒙端适配层可直接映射为 ArkTS 的 string 类型,避免多端数据类型解析差异导致的症状信息记录错误,尤其在“疼痛 中度 腰部疼痛影响睡眠”这类核心症状信息的传递上,保证了跨端的数据准确性;
  • Counseling 包含心理疏导ID、标题、内容、咨询师,字段类型均为 string,鸿蒙端适配层可直接映射为 ArkTS 的 string 类型,保证心理疏导服务信息展示的跨端准确性,符合临终关怀对服务提供者信息透明化的核心要求;
  • Wish 采用“患者姓名+心愿内容+日期”的人文属性数据结构设计,日期字段通过 new Date().toISOString().split('T')[0] 生成标准日期格式字符串,鸿蒙端适配层可直接解析,保证心愿记录的时间维度信息跨端一致;
  • SpiritualResource 包含资源ID、标题、描述、链接,链接字段(link)为通用字符串格式,鸿蒙端适配层可直接映射为 ArkTS 的 string 类型,保证灵性关怀资源链接的跨端可访问性。

这种强类型+场景化的数据模型设计,在跨端场景下保证了数据结构的一致性——鸿蒙端适配层可直接解析 TypeScript 类型定义,与 ArkTS 中的数据模型形成精准映射,避免多端数据格式不一致导致的症状信息记录异常、心愿内容展示错误等核心问题,是晚期患者关怀场景跨端落地的基础保障。

2. Hooks 状态管理

应用采用 useState 实现多维度状态管理,核心状态均具备跨端复用的特性:

  • 核心业务状态(symptoms/counselings/wishes/spiritualResources)中,counselings/spiritualResources 为只读设计,适配层自动映射为鸿蒙的 @State 响应式状态,心理疏导/灵性关怀资源列表的展示逻辑跨端统一;symptoms/wishes 支持动态新增(setSymptoms/setWishes),该更新方法在鸿蒙端会被适配层转换为 ArkTS 的 @State 状态更新逻辑,新增症状/心愿后列表可实时渲染,保证多端关怀数据展示的一致性;
  • 表单状态(newSymptom/newWish)维护症状/心愿录入的核心信息,采用对象式状态管理,更新逻辑(setNewSymptom({ ...newSymptom, name: text }))使用对象扩展运算符,为 ES6+ 标准语法,鸿蒙端直接执行,表单输入的双向绑定逻辑跨端统一;
  • 弹窗状态(isModalVisible/modalContent)维护弹窗显隐与内容,其更新逻辑为基础状态操作,鸿蒙端适配层会将 Modal 的显示状态映射为 ArkUI 弹窗的显隐状态,弹窗展示关怀资源详情的逻辑跨端统一。

应用在基础样式之上新增症状卡片、心理疏导卡片、心愿卡片、灵性关怀资源卡片专属样式,核心样式设计仍遵循跨端兼容原则,适配鸿蒙系统无明显改造成本,且针对晚期患者关怀场景的样式特性做了人文化优化:

  • Flex 布局的跨端统一:从症状录入表单的“横向输入行”、各类关怀卡片的“图标+信息”布局,到弹窗的“垂直居中+内容区”布局,全量采用 Flex 布局体系——症状/心愿录入表单使用 flexDirection: 'row' + justifyContent: 'space-between' 实现输入框均分排列,各类关怀卡片使用 flexDirection: 'row' + alignItems: 'center' 横向布局,保证信息展示的层次感。Flex 作为 W3C 标准布局方案,在鸿蒙端可被适配层直接解析为 ArkUI 的 Flex 布局,无需重构任何布局逻辑,仅需保证样式属性命名与 React Native 规范一致,尤其在症状录入、心愿记录等核心信息交互区域的布局上,Flex 布局的跨端一致性表现突出;
  • 晚期关怀专属样式的跨端适配
    • 各类关怀卡片样式(symptomCard/counselingCard/wishCard/resourceCard)采用统一的浅蓝背景(#f0f9ff)、圆角(12)、内边距(16)设计,为通用样式属性,鸿蒙端适配层会将这些属性转换为 ArkUI 的对应样式,卡片的视觉质感跨端统一,符合临终关怀场景温和、舒缓的视觉需求;
    • 表单输入框样式(inputbackgroundColor: '#f0f9ff' + borderRadius: 8 + padding)为通用样式属性,鸿蒙端适配层会将输入框样式转换为 ArkUI 的 TextInput 对应样式,输入框的视觉效果、内边距、圆角跨端统一,保证症状/心愿信息录入的交互体验一致;
    • 添加按钮样式(addButton)采用低饱和度蓝色(#0284c7)、圆角(8)设计,样式属性均为通用属性,鸿蒙端直接解析,按钮的视觉效果与点击区域跨端一致,符合临终关怀场景温和的交互风格;
  • 屏幕适配与层级兼容Dimensions.get('window') 获取设备宽高的 API 在鸿蒙端已完成原生映射,为不同尺寸鸿蒙设备(手机、平板)的自适应布局预留基础;shadow + elevation 的双层阴影设计,鸿蒙系统对 elevation 属性的支持与 Android 端完全兼容,保证各类关怀卡片、信息卡片的视觉层级跨端统一,同时阴影透明度(0.1)的低饱和度设计,符合临终关怀场景的视觉调性;
  • 安全区域适配SafeAreaView 组件在鸿蒙端已适配为 ArkUI 的 SafeArea 组件,保证头部晚期患者关怀标题区域在不同鸿蒙设备上的展示完整性,避免标题被刘海屏、全面屏遮挡。

(1)症状管理

症状管理组件是晚期患者关怀的核心功能模块,核心适配逻辑如下:

  • 症状录入表单采用 TextInput 组件实现双向绑定,onChangeText 回调中的状态更新逻辑使用对象扩展运算符,为 ES6+ 标准语法,鸿蒙端直接执行,表单输入的实时更新逻辑跨端一致;
  • 症状添加逻辑(handleAddSymptom)包含完整的合法性校验:
    1. 空值校验(newSymptom.name && newSymptom.severity && newSymptom.description)为纯 JS 布尔运算,鸿蒙端直接执行,校验规则(症状名称/严重程度/描述必填)跨端一致,保证症状记录的完整性;
    2. 新症状对象生成逻辑采用 ES6 对象字面量语法,ID 生成((symptoms.length + 1).toString())为纯 JS 数值运算 + 类型转换,鸿蒙端直接执行,症状 ID 生成规则跨端一致;
    3. 症状列表更新(setSymptoms([...symptoms, newSymptomEntry]))使用数组扩展运算符,鸿蒙端直接执行,新增症状的规则跨端一致;
  • 症状列表渲染采用 map 方法遍历 symptoms 数组,该逻辑为纯 JS 数组操作,鸿蒙端通过 JS 引擎直接执行,列表渲染的顺序与症状信息展示的完整性跨端一致,保证症状记录的准确性;
  • 反馈提示(Alert.alert)会被适配层转换为鸿蒙的 AlertDialog 组件,提示内容分“成功/失败”两种场景,跨端展示与交互逻辑完全一致,且提示文案的温和性设计符合临终关怀场景的人文需求。
(2)心愿记录

心愿记录组件是晚期患者关怀的人文核心模块,核心适配逻辑如下:

  • 心愿录入表单采用 TextInput 组件实现双向绑定,状态更新逻辑为 ES6+ 标准语法,鸿蒙端直接执行,表单输入的实时更新逻辑跨端一致;
  • 心愿添加逻辑(handleAddWish)包含合法性校验与日期自动生成:
    1. 空值校验(newWish.patientName && newWish.wishText)为纯 JS 布尔运算,鸿蒙端直接执行,校验规则(患者姓名/心愿内容必填)跨端一致,保证心愿记录的完整性;
    2. 日期生成逻辑(new Date().toISOString().split('T')[0])为纯 JS 日期处理 API,鸿蒙端直接执行,日期格式(YYYY-MM-DD)跨端统一,保证心愿记录的时间维度准确性;
    3. 心愿列表更新逻辑使用数组扩展运算符,鸿蒙端直接执行,新增心愿的规则跨端一致;
  • 心愿列表渲染采用 map 方法遍历 wishes 数组,该逻辑为纯 JS 数组操作,鸿蒙端直接执行,列表渲染的顺序与心愿信息展示的完整性跨端一致,保证心愿记录的人文属性不丢失。
(3)关怀资源查看

心理疏导与灵性关怀资源查看组件是晚期患者关怀的重要补充模块,核心适配逻辑如下:

  • 关怀资源列表渲染采用 map 方法遍历 counselings/spiritualResources 数组,该逻辑为纯 JS 数组操作,鸿蒙端直接执行,列表渲染的顺序与资源信息展示的完整性跨端一致;
  • 资源详情查看逻辑(handleViewCounseling/handleViewResource)包含数据关联查找:
    1. 资源查找(counselings.find(c => c.id === counselingId)/spiritualResources.find(r => r.id === resourceId))为纯 JS 数组方法,鸿蒙端直接执行;
    2. 弹窗内容拼接(setModalContent)采用字符串换行拼接,该逻辑为通用 JS 字符串操作,鸿蒙端直接执行,拼接后的资源详情格式(标题/内容/咨询师/链接)跨端统一,保证用户可清晰查看完整的关怀资源信息;
  • Modal 组件的核心属性(animationType/transparent/visible/onRequestClose)在鸿蒙端会被适配层转换为 ArkUI 的 Dialog 组件对应属性,滑动动画(slide)、透明背景(transparent: true)的逻辑跨端一致,弹窗的温和过渡效果符合临终关怀场景的交互调性。

1. 症状添加

handleAddSymptomhandleAddWish 是晚期患者关怀的核心业务逻辑,分别实现了“合法性校验-记录生成-列表更新-表单重置-反馈提示”的全流程症状添加与心愿记录,核心适配逻辑如下:

  • 合法性校验逻辑为纯 JS 布尔运算组合,无任何平台依赖,鸿蒙端直接执行,校验规则(症状信息必填、心愿信息必填)跨端一致,保证关怀数据记录的规范性;
  • 新记录对象生成逻辑中,ID 生成((symptoms.length + 1).toString()/(wishes.length + 1).toString())为纯 JS 数值运算 + 类型转换,鸿蒙端直接执行,记录 ID 生成规则跨端一致;心愿记录的日期生成逻辑为纯 JS 日期 API 操作,鸿蒙端直接执行,日期格式跨端统一;
  • 列表更新逻辑使用数组扩展运算符,为 ES6+ 标准语法,鸿蒙端直接执行,列表的更新规则跨端一致,保证新增症状/心愿实时展示;
  • 表单重置逻辑为基础对象赋值,鸿蒙端直接执行,重置规则跨端一致,保证提交记录后表单清空;
  • 反馈提示逻辑使用 Alert.alert API,鸿蒙端适配层转换为 AlertDialog 组件,提示内容分场景设计且文案温和,跨端展示与交互逻辑完全一致,符合临终关怀场景的人文需求。

2. 关怀资源详情

handleViewCounselinghandleViewResource 是晚期患者关怀的核心信息补充逻辑,核心适配逻辑如下:

  • 资源查找逻辑采用数组 find 方法,为纯 JS 数组操作,鸿蒙端直接执行,查找规则跨端一致,保证资源信息的精准匹配;
  • 弹窗内容拼接逻辑为通用 JS 字符串操作,鸿蒙端直接执行,拼接后的资源详情格式跨端统一,保证信息展示的完整性与可读性;
  • 弹窗显隐状态更新逻辑为基础 useState 操作,鸿蒙端适配层转换为 ArkUI 弹窗的显隐控制逻辑,弹窗的展示/关闭逻辑跨端一致。

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

  • 数组 API:map/find/扩展运算符等数组方法为 JS 原生 API,鸿蒙端通过 JS 引擎直接执行,无需适配,保证症状/心愿/关怀资源列表的渲染、查找、更新等核心逻辑的跨端一致性;
  • 字符串 API:字符串拼接/换行符(\n)等操作为 JS 原生 API,鸿蒙端直接执行,保证弹窗内容拼接等核心逻辑的跨端一致性;
  • 日期 API:new Date().toISOString() 等日期处理 API 为 JS 原生 API,鸿蒙端直接执行,保证心愿记录日期生成的跨端一致性;
  • 表单 API:TextInput 组件的 onChangeText/value 属性在鸿蒙端已完成适配,双向绑定逻辑跨端一致,保证症状/心愿信息录入的交互体验统一;
  • 弹窗 API:Alert.alert/Modal 已被适配层封装为鸿蒙的 AlertDialog/Dialog 组件,交互逻辑完全复用,在症状添加反馈、心愿记录反馈、关怀资源详情展示等核心场景中,弹窗的展示与操作逻辑多端统一;
  • 样式 API:StyleSheet.create 封装的样式规则,适配层转换为 ArkUI 的样式对象,各类关怀卡片、输入框、按钮的样式属性均为通用属性,无需修改即可适配鸿蒙。

该晚期患者关怀应用作为智慧医疗人文关怀核心模块,适配鸿蒙系统的成本极低,核心适配思路与技术要点如下:

应用核心的症状添加、心愿记录、资源查找、合法性校验等逻辑均为纯 JS 实现,无任何平台相关依赖,这是跨端复用的最大优势——鸿蒙端可通过 JS 引擎直接执行该逻辑,无需适配任何原生能力。在生产环境中扩展症状编辑/删除、心愿分享、资源跳转等逻辑时,新增规则仍为纯 JS 逻辑,鸿蒙端可直接复用,仅需保证规则逻辑的通用性,无需考虑平台差异,这也是晚期患者关怀场景跨端开发的核心优势。

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

鸿蒙系统有自身的设计规范,在适配时可通过条件编译实现差异化样式,既保证遵循鸿蒙设计规范,又能保留现有代码的完整性与人文调性:

// 鸿蒙端晚期患者关怀样式差异化适配示例
import { Platform } from 'react-native';
const isHarmonyOS = Platform.OS === 'harmony';

const adaptiveStyles = {
  symptomCard: {
    ...styles.symptomCard,
    backgroundColor: isHarmonyOS ? '#e0f7fa' : '#f0f9ff',
    borderRadius: isHarmonyOS ? 14 : 12,
  },
  wishCard: {
    ...styles.wishCard,
    backgroundColor: isHarmonyOS ? '#e0f7fa' : '#f0f9ff',
    borderRadius: isHarmonyOS ? 14 : 12,
  },
  input: {
    ...styles.input,
    backgroundColor: isHarmonyOS ? '#e0f7fa' : '#f0f9ff',
    borderRadius: isHarmonyOS ? 10 : 8,
  },
  addButton: {
    ...styles.addButton,
    backgroundColor: isHarmonyOS ? '#0369a1' : '#0284c7',
    borderRadius: isHarmonyOS ? 10 : 8,
  }
};

这种轻量级的差异化适配,既能保证符合鸿蒙的设计规范,又能保留现有代码的完整性,尤其在症状卡片、心愿卡片、录入表单等核心晚期关怀交互组件的样式适配中,效果显著,同时维持了临终关怀场景温和、舒缓的视觉调性。

该 React Native 晚期患者关怀应用实现了症状管理、心理疏导、心愿记录、灵性关怀资源查看等核心智慧医疗人文关怀功能,代码结构符合跨端开发规范,可低成本适配鸿蒙系统。针对生产环境落地,可做以下优化:

  1. 症状严重程度标准化校验:新增症状严重程度的下拉选择(轻度/中度/重度)与标准化校验,校验逻辑为纯 JS 字符串匹配实现,鸿蒙端直接执行,提升症状记录的规范性;
  2. 心愿记录富文本支持:扩展心愿录入框为富文本输入,富文本处理逻辑为纯 JS 实现,鸿蒙端直接执行,满足患者/家属更丰富的心愿表达需求;
  3. 关怀资源链接跳转适配:通过 React Native 原生模块封装鸿蒙的浏览器 API,实现灵性关怀资源链接的一键跳转,核心关怀逻辑可完全复用现有代码,仅需对接鸿蒙的浏览器原生 API,提升资源访问的便捷性;
  4. 数据持久化与同步:引入 AsyncStorage(或鸿蒙原生 Preferences)实现症状/心愿/关怀资源数据的本地加密存储,同时对接医疗云平台接口实现数据云端同步,鸿蒙端兼容主流存储方案,可直接复用数据处理逻辑,保证关怀数据的跨设备同步;
  5. 家属权限管理扩展:新增家属账号权限管理逻辑,权限校验为纯 JS 逻辑,鸿蒙端直接执行,完善晚期患者关怀的多角色协作体系。

真实演示案例代码:






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

// Base64 图标库
const ICONS_BASE64 = {
  symptom: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
  counseling: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
  wish: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
  resources: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
};

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

// 症状类型
type Symptom = {
  id: string;
  name: string;
  severity: string;
  description: string;
};

// 心理疏导类型
type Counseling = {
  id: string;
  title: string;
  content: string;
  therapist: string;
};

// 心愿类型
type Wish = {
  id: string;
  patientName: string;
  wishText: string;
  date: string;
};

// 灵性关怀资源类型
type SpiritualResource = {
  id: string;
  title: string;
  description: string;
  link: string;
};

// 晚期患者关怀应用组件
const EndOfLifeCareApp: React.FC = () => {
  const [symptoms, setSymptoms] = useState<Symptom[]>([
    {
      id: '1',
      name: '疼痛',
      severity: '中度',
      description: '患者主诉腰部疼痛,影响睡眠'
    },
    {
      id: '2',
      name: '呼吸困难',
      severity: '轻度',
      description: '轻微气短,活动后加重'
    }
  ]);

  const [counselings] = useState<Counseling[]>([
    {
      id: '1',
      title: '情绪疏导',
      content: '帮助患者缓解焦虑和恐惧情绪',
      therapist: '张心理咨询师'
    },
    {
      id: '2',
      title: '家庭关系调解',
      content: '协助患者与家属沟通,改善家庭关系',
      therapist: '李心理咨询师'
    }
  ]);

  const [wishes, setWishes] = useState<Wish[]>([
    {
      id: '1',
      patientName: '李先生',
      wishText: '希望能在家中安详度过最后时光',
      date: '2023-12-01'
    }
  ]);

  const [spiritualResources] = useState<SpiritualResource[]>([
    {
      id: '1',
      title: '佛教临终关怀',
      description: '提供佛教背景的临终关怀指导',
      link: 'https://example.com/buddhism'
    },
    {
      id: '2',
      title: '基督教安慰祷告',
      description: '提供基督教背景的安慰祷告资源',
      link: 'https://example.com/christianity'
    }
  ]);

  const [newSymptom, setNewSymptom] = useState({
    name: '',
    severity: '',
    description: ''
  });

  const [newWish, setNewWish] = useState({
    patientName: '',
    wishText: ''
  });

  const [isModalVisible, setIsModalVisible] = useState(false);
  const [modalContent, setModalContent] = useState('');

  const handleAddSymptom = () => {
    if (newSymptom.name && newSymptom.severity && newSymptom.description) {
      const newSymptomEntry: Symptom = {
        id: (symptoms.length + 1).toString(),
        name: newSymptom.name,
        severity: newSymptom.severity,
        description: newSymptom.description
      };
      setSymptoms([...symptoms, newSymptomEntry]);
      setNewSymptom({ name: '', severity: '', description: '' });
      Alert.alert('添加成功', '症状已添加到管理列表中');
    } else {
      Alert.alert('提示', '请填写完整的症状信息');
    }
  };

  const handleAddWish = () => {
    if (newWish.patientName && newWish.wishText) {
      const newWishEntry: Wish = {
        id: (wishes.length + 1).toString(),
        patientName: newWish.patientName,
        wishText: newWish.wishText,
        date: new Date().toISOString().split('T')[0]
      };
      setWishes([...wishes, newWishEntry]);
      setNewWish({ patientName: '', wishText: '' });
      Alert.alert('添加成功', '心愿已添加到记录中');
    } else {
      Alert.alert('提示', '请填写完整的心愿信息');
    }
  };

  const handleViewCounseling = (counselingId: string) => {
    const counseling = counselings.find(c => c.id === counselingId);
    if (counseling) {
      setModalContent(`标题: ${counseling.title}\n内容: ${counseling.content}\n心理咨询师: ${counseling.therapist}`);
      setIsModalVisible(true);
    }
  };

  const handleViewResource = (resourceId: string) => {
    const resource = spiritualResources.find(r => r.id === resourceId);
    if (resource) {
      setModalContent(`标题: ${resource.title}\n描述: ${resource.description}\n链接: ${resource.link}`);
      setIsModalVisible(true);
    }
  };

  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>
          <View style={styles.inputRow}>
            <TextInput
              style={styles.input}
              placeholder="症状名称"
              value={newSymptom.name}
              onChangeText={(text) => setNewSymptom({ ...newSymptom, name: text })}
            />
            <TextInput
              style={styles.input}
              placeholder="严重程度"
              value={newSymptom.severity}
              onChangeText={(text) => setNewSymptom({ ...newSymptom, severity: text })}
            />
          </View>
          <View style={styles.inputRow}>
            <TextInput
              style={styles.input}
              placeholder="症状描述"
              value={newSymptom.description}
              onChangeText={(text) => setNewSymptom({ ...newSymptom, description: text })}
            />
          </View>
          <TouchableOpacity 
            style={styles.addButton}
            onPress={handleAddSymptom}
          >
            <Text style={styles.addText}>添加症状</Text>
          </TouchableOpacity>
          {symptoms.map(symptom => (
            <View key={symptom.id} style={styles.symptomCard}>
              <Text style={styles.icon}>🤒</Text>
              <View style={styles.cardInfo}>
                <Text style={styles.cardTitle}>{symptom.name}</Text>
                <Text style={styles.cardDescription}>严重程度: {symptom.severity}</Text>
                <Text style={styles.cardDescription}>描述: {symptom.description}</Text>
              </View>
            </View>
          ))}
        </View>

        {/* 心理疏导 */}
        <View style={styles.section}>
          <Text style={styles.sectionTitle}>心理疏导</Text>
          {counselings.map(counseling => (
            <TouchableOpacity 
              key={counseling.id}
              style={styles.counselingCard}
              onPress={() => handleViewCounseling(counseling.id)}
            >
              <Text style={styles.icon}>🧠</Text>
              <View style={styles.cardInfo}>
                <Text style={styles.cardTitle}>{counseling.title}</Text>
                <Text style={styles.cardDescription}>心理咨询师: {counseling.therapist}</Text>
              </View>
            </TouchableOpacity>
          ))}
        </View>

        {/* 心愿记录 */}
        <View style={styles.section}>
          <Text style={styles.sectionTitle}>心愿记录</Text>
          <View style={styles.inputRow}>
            <TextInput
              style={styles.input}
              placeholder="患者姓名"
              value={newWish.patientName}
              onChangeText={(text) => setNewWish({ ...newWish, patientName: text })}
            />
            <TextInput
              style={styles.input}
              placeholder="心愿内容"
              value={newWish.wishText}
              onChangeText={(text) => setNewWish({ ...newWish, wishText: text })}
            />
          </View>
          <TouchableOpacity 
            style={styles.addButton}
            onPress={handleAddWish}
          >
            <Text style={styles.addText}>记录心愿</Text>
          </TouchableOpacity>
          {wishes.map(wish => (
            <View key={wish.id} style={styles.wishCard}>
              <Text style={styles.icon}>愿望</Text>
              <View style={styles.cardInfo}>
                <Text style={styles.cardTitle}>{wish.patientName}</Text>
                <Text style={styles.cardDescription}>心愿: {wish.wishText}</Text>
                <Text style={styles.cardDescription}>日期: {wish.date}</Text>
              </View>
            </View>
          ))}
        </View>

        {/* 灵性关怀资源 */}
        <View style={styles.section}>
          <Text style={styles.sectionTitle}>灵性关怀资源</Text>
          {spiritualResources.map(resource => (
            <TouchableOpacity 
              key={resource.id}
              style={styles.resourceCard}
              onPress={() => handleViewResource(resource.id)}
            >
              <Text style={styles.icon}>🙏</Text>
              <View style={styles.cardInfo}>
                <Text style={styles.cardTitle}>{resource.title}</Text>
                <Text style={styles.cardDescription}>{resource.description}</Text>
              </View>
            </TouchableOpacity>
          ))}
        </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,
  },
  inputRow: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    marginBottom: 12,
  },
  input: {
    flex: 1,
    backgroundColor: '#f0f9ff',
    borderRadius: 8,
    paddingHorizontal: 12,
    paddingVertical: 8,
    fontSize: 14,
    color: '#0c4a6e',
    marginRight: 8,
  },
  addButton: {
    backgroundColor: '#0284c7',
    padding: 12,
    borderRadius: 8,
    alignItems: 'center',
  },
  addText: {
    color: '#ffffff',
    fontSize: 14,
    fontWeight: '500',
  },
  symptomCard: {
    flexDirection: 'row',
    alignItems: 'center',
    backgroundColor: '#f0f9ff',
    borderRadius: 12,
    padding: 16,
    marginBottom: 12,
  },
  counselingCard: {
    flexDirection: 'row',
    alignItems: 'center',
    backgroundColor: '#f0f9ff',
    borderRadius: 12,
    padding: 16,
    marginBottom: 12,
  },
  wishCard: {
    flexDirection: 'row',
    alignItems: 'center',
    backgroundColor: '#f0f9ff',
    borderRadius: 12,
    padding: 16,
    marginBottom: 12,
  },
  resourceCard: {
    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,
  },
  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 EndOfLifeCareApp;

请添加图片描述


打包

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

在这里插入图片描述

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

在这里插入图片描述

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

请添加图片描述
本文分析了一个基于React Native开发的晚期患者关怀应用的技术实现及鸿蒙适配策略。应用采用函数式组件设计,结合TypeScript类型系统确保代码安全,使用Flexbox布局实现响应式设计。功能模块包括症状管理、心愿记录、心理疏导和灵性关怀,均通过独立状态管理实现。应用充分利用React Native跨平台特性,使用核心组件如ScrollView、Modal等,这些组件在鸿蒙系统中均有对应实现。该架构设计有助于在鸿蒙系统上获得良好性能表现,为医疗健康领域的跨平台开发提供了实践参考。

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

Logo

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

更多推荐