React Native for OpenHarmony 三方库集成实战:巡检表单

发布时间:2026/9/29 22:15:21
React Native for OpenHarmony 三方库集成实战:巡检表单 React Native for OpenHarmony 三方库集成实战巡检表单验证日期2026-09-26受测宿主RN能力库0.3.1一、应用背景现场巡检表单通常同时包含人员角色、若干安全检查项、流程进度和提交结果。角色选择器、复选框、步骤指示器和 Toast 解决的是不同的 UI 问题但它们最终都要写入同一份业务状态。若让每个组件自己改变步骤或决定提交成功页面很快会出现“视觉上进入下一步、服务端实际未提交”的不一致。本文把四个纯 JavaScript 组件放在一个受控表单中组件只报告用户操作reducer管理状态提交函数负责本地校验和幂等请求服务端响应再决定流程是否迁移。图 1执行人已选中、安全检查已确认提交后流程进入第 2 步。二、应用目标用角色选择器维护稳定的业务值operator/reviewer用复选框完成提交前的安全检查用步骤指示器展示当前流程位置但不绕过服务端状态机用 Toast 做摘要反馈同时把错误保留在页面状态中防止重复点击、页面离开和网络重试产生重复提交。三、三方库与版本三方库锁定版本适配 TAG职责react-native-switch-selector2.3.02.3.0-ohos-1.0.0执行人/复核人选择react-native-check-box2.1.72.1.7-ohos-1.0.0安全检查状态react-native-step-indicator1.0.31.0.3-ohos-1.0.0流程进度react-native-toast-message2.5.22.5.2-ohos-1.0.0成功与失败反馈四个包均为 MIT 许可证的 OpenHarmony 交付包版本、源仓库和 TAG 截止2026-09-26核对。它们由 Metro 打包为 JavaScript不引入 HAR 或新的系统权限。npminstallnpmrun bundle:harmony四、应用方式页面状态用零基step保存显示时再加一。组件的onPress和onClick只派发动作不直接调用接口const [role, setRole] useStateoperator | reviewer(operator); const [checked, setChecked] useState(false); const [step, setStep] useState(0); SwitchSelector initial{0} onPress{value setRole(value as operator | reviewer)} options{[ {label: 执行人, value: operator}, {label: 复核人, value: reviewer}, ]} buttonColor#17202A backgroundColor#E9EDF0 selectedColor#FFFFFF height{40} / CheckBox isChecked{checked} onClick{() setChecked(value !value)} rightText安全检查已完成 checkBoxColor#316B9B / StepIndicator currentPosition{step} stepCount{4} labels{[创建, 检查, 复核, 归档]} customStyles{stepStyles} / Pressable onPress{submit} disabled{status submitting} Text{status submitting ? 提交中... : 提交流程表单}/Text /Pressable {/* Toast 容器在应用根节点只渲染一次 */} Toast /步骤指示器可以展示当前进度但不能把onPress直接接到setStep。是否允许跳转、回退或进入归档步骤应由领域状态和服务端响应决定。五、工程实现用 reducer 统一状态迁移。多个布尔值很容易形成冲突组合例如submittingtrue同时又submittedtrue。使用明确的状态和操作 ID让重复提交在入口处被拦截type FormStatus draft | validating | submitting | submitted | failed; type Role operator | reviewer; type FormState { role: Role; checked: boolean; step: number; status: FormStatus; operationId?: string; error?: string; }; type Action | {type: roleChanged; role: Role} | {type: checkChanged; checked: boolean} | {type: submitStarted; operationId: string} | {type: submitSucceeded; nextStep: number} | {type: submitFailed; message: string}; function formReducer(state: FormState, action: Action): FormState { switch (action.type) { case roleChanged: return state.status submitting ? state : {...state, role: action.role}; case checkChanged: return {...state, checked: action.checked, error: undefined}; case submitStarted: return {...state, status: submitting, operationId: action.operationId}; case submitSucceeded: return {...state, status: submitted, step: action.nextStep, error: undefined}; case submitFailed: return {...state, status: failed, error: action.message}; } }角色值保存稳定标识展示文案可以本地化。复选框是 UI 状态不等于服务端已经完成安全检查提交时仍需把checked放入请求并由服务端重新校验。提交使用幂等键和错误分层。本地校验只负责快速反馈权限、流程版本和业务规则由服务端校验。超时不等于服务端没有收到请求重试前应使用同一个幂等键查询状态async function submitForm() { if (state.status submitting) return; if (!state.checked) { dispatch({type: submitFailed, message: 请先完成安全检查}); Toast.show({type: error, text1: 表单未提交, text2: 安全检查未完成}); return; } const operationId ${Date.now()}-${Math.random().toString(16).slice(2)}; dispatch({type: submitStarted, operationId}); try { const result await api.submitForm({ role: state.role, checked: state.checked, step: state.step, idempotencyKey: operationId, }); dispatch({type: submitSucceeded, nextStep: result.nextStep}); Toast.show({type: success, text1: 表单已提交, text2: 流程 ${result.nextStep 1}/4}); } catch (error) { const message mapSubmitError(error); dispatch({type: submitFailed, message}); Toast.show({type: error, text1: 提交失败, text2: message}); } }网络错误可以有限重试权限拒绝要重新登录或申请权限版本冲突要刷新表单字段校验失败要定位到具体字段。不要把所有异常都映射为“请重试”。提交成功后以服务端返回的流程状态更新step不要只执行step 1。Toast、键盘和离线草稿。Toast 是摘要反馈错误仍要显示在字段下方用户切换到其他页面后页面状态仍应能说明为什么没有提交。键盘提交和点击提交调用同一个submitForm()失败后将焦点移到第一个错误字段。现场网络不稳定时可以保存带schemaVersion、表单 ID、修改时间和幂等键的草稿。草稿保存、服务端提交和正式审计是三个不同事件不能因为本地保存成功就显示“已提交”。离线队列恢复时sending状态要能够回退为可重试并用幂等键避免服务端重复写入。检查项不要使用数组下标作为业务 ID。服务端下发规则变化后数组顺序可能改变下标会把旧草稿的结果套到错误的检查项上。草稿和提交 DTO 都使用稳定的checkIdtypeCheckValue{checkId:string;checked:boolean;note:string;};typeFormDraft{schemaVersion:2;formId:string;workflowVersion:string;role:operator|reviewer;checks:CheckValue[];step:number;updatedAt:string;idempotencyKey:string;};functiontoSubmitDto(draft:FormDraft){return{formId:draft.formId,workflowVersion:draft.workflowVersion,role:draft.role,checks:draft.checks.map(check({id:check.checkId,value:check.checked,note:check.note.trim(),})),idempotencyKey:draft.idempotencyKey,};}展示模型可以包含展开状态、错误文案和本地化 label提交 DTO 只包含服务端需要的 ID、值、备注和版本。不要直接JSON.stringifyReact state因为 state 里可能包含错误对象、动画状态和未清理的临时字段。离线队列使用显式状态。提交请求发出后客户端可能被系统杀死队列项需要知道下一次启动时能否重试typeQueueStatequeued|sending|acknowledged|rejected|conflict;typeQueueItem{key:string;state:QueueState;attempts:number;lastError?:string;payload:ReturnTypetypeoftoSubmitDto;};functionrecoverQueue(items:QueueItem[]){returnitems.map(itemitem.statesending?{...item,state:queuedasconst}:item);}sending回退为queued只代表客户端没有收到确认服务端可能已经成功因此重试必须沿用原幂等键并优先调用getSubmissionStatus(key)。字段校验失败不重试版本冲突刷新后让用户确认网络错误才使用有限次数的指数退避。把可访问性作为表单契约。角色控件声明选择语义复选框声明checkbox提交按钮声明button。步骤指示器如果不能跳转应作为进度文本而不是一组可点击按钮Pressable accessibilityRolebutton accessibilityLabel提交巡检表单 accessibilityState{{disabled: state.status submitting}} disabled{state.status submitting} onPress{submitForm} Text提交流程表单/Text /Pressable {state.error ( Text accessibilityRolealert{state.error}/Text )}错误文本放在控件下方而不是覆盖输入区域。大字体和长文案下按钮允许换行Toast 只做摘要详细错误仍然留在页面上。处理流程版本冲突。用户打开表单后另一个终端可能已经完成复核。提交 DTO 携带workflowVersion服务端发现版本过期时返回conflict客户端保留本地草稿并要求刷新不能自动把旧表单覆盖回去typeSubmitError|{code:network;retryable:true}|{code:timeout;retryable:false}|{code:permission;retryable:false}|{code:validation;fields:Recordstring,string}|{code:conflict;serverVersion:string};functionmapSubmitError(error:unknown):string{constcodegetErrorCode(error);if(codeconflict)return表单已被其他终端更新请刷新后再提交;if(codevalidation)return请修正标记的检查项;if(codepermission)return当前角色无权提交此步骤;if(codetimeout)return请求超时请先查询提交状态;return网络不可用请稍后重试;}服务端返回的新流程状态、负责人和下一步必填项都应写入领域状态再由步骤指示器渲染。客户端的step 1只能用于演示组件不应作为正式迁移规则。自动保存需要可重复迁移。表单 schema 增加必填项时旧草稿不能直接强制转换成新类型。迁移函数应是纯函数保存原始 schema 版本失败时保留原始草稿typeDraftV1{formId:string;checked:boolean;note:string};typeDraftV2DraftV1{checkId:string};functionmigrateDraft(input:DraftV1|DraftV2):DraftV2{if(checkIdininput)returninput;return{...input,checkId:safety-check,};}自动保存应去抖避免每次按键都写磁盘写入任务也要带序号旧写入完成后不能覆盖较新的草稿。用户退出账号、删除工单或卸载应用时按产品规则清理包含备注、位置和附件引用的本地数据。返回键和顶部返回按钮都调用同一个attemptLeave()有未保存修改时保存草稿或确认离开提交中则继续等待任务中心或明确取消。不能因为组件卸载就把已经发出的请求当成失败也不能在未收到服务端确认时显示成功。asyncfunctionattemptLeave(){if(state.statussubmitting){return{allowed:false,reason:submitting}asconst;}if(draftIsDirty(state)){awaitsaveDraft(state);return{allowed:true,reason:draft-saved}asconst;}return{allowed:true,reason:clean}asconst;}把离开决策放在业务层后系统返回键、顶部按钮和通知深链可以共享同一规则避免某条路径把用户输入直接丢弃。组件测试和真机测试。组件测试验证默认角色、角色切换、勾选、步骤边界和 Toast 调用业务测试验证未勾选提交、重复点击、超时、权限拒绝和版本冲突。真机测试再检查触摸区域、键盘、返回键、系统字体和前后台切换。it(does not submit when the safety check is incomplete,async(){constsubmitjest.fn();conststate{checked:false,status:draftasconst};awaitsubmitFormWith({state,api:{submitForm:submit}});expect(submit).not.toHaveBeenCalled();expect(Toast.show).toHaveBeenCalledWith(expect.objectContaining({type:error}));});六、真机验证验证项实测结果结论HAP 安装与启动RN能力库 0.3.1可启动通过角色选择默认显示执行人通过安全检查复选框可选中通过表单提交显示“表单已提交 · 执行人 · 流程 2/4”通过Toast成功反馈显示在根容器通过受测设备为6UMBB26319007180系统OpenHarmony-7.0.0.105HAP SHA-256a0f079982142ef5eb836f439af5e71c8f31f33c4988e80ab2a7575bee64b1f03。图 1 来自同一受测 HAP。图 2react-native-step-indicator库级真机验证中的进度与评分场景截图来自2026-09-14的独立包验证。图 3react-native-toast-message库级真机验证中的提示与菜单场景。图 4react-native-check-box与选择控件的库级真机验证场景。本轮真机证据覆盖默认角色、已勾选提交和成功 Toast未覆盖真实后端错误、未勾选提交、离线冲突、草稿恢复、长文案和屏幕阅读器。接入真实接口后必须新增错误分支证据不能把 Demo 中的本地步骤迁移直接当成服务端流程完成。七、参考链接react-native-switch-selectorreact-native-check-boxreact-native-step-indicatorreact-native-toast-messageRN能力库欢迎加入 RN for OpenHarmony 社区。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询