目录目标与背景Axios 简介与优势安装与配置项目集成步骤代码实现详解错误处理与异常管理自定义 Hook 封装UI 组件实现最佳实践与优化建议测试与验证常见问题与解决方案总结ℹ️ 说明axios三方库在适配开源鸿蒙过程不涉及代码修改可直接引入。 目标与背景 项目需求在 React Native 开源鸿蒙项目中需要集成 Axios 库来实现网络请求功能并通过AtomGit API 获取并展示用户信息。 技术选型Axios: 基于 Promise 的 HTTP 客户端支持浏览器和 Node.js优势:自动转换 JSON 数据请求/响应拦截器取消请求超时处理更好的错误处理机制支持 TypeScript API 接口接口地址:https://api.atomgit.com/api/v5/users/{username}请求方法: GET返回格式: JSON示例:https://api.atomgit.com/api/v5/users/CodexBai⚡️ Axios 简介与优势为什么选择 Axios相比 React Native 原生的fetchAPIAxios 提供了更丰富的功能和更好的开发体验特性FetchAxios自动 JSON 转换❌ 需要手动调用.json()✅ 自动转换请求超时❌ 需要手动实现✅ 内置支持请求取消⚠️ 需要 AbortController✅ 内置支持拦截器❌ 不支持✅ 支持请求/响应拦截错误处理⚠️ 需要手动检查状态码✅ 自动处理 HTTP 错误TypeScript 支持⚠️ 需要额外类型定义✅ 原生支持请求/响应数据转换❌ 不支持✅ 支持️ 安装与配置 使用 npm 安装在RNOH Bundle工程根目录打开终端执行以下命令安装axios。npminstallaxios1.6.7ℹ️ 说明1.6.7为指定安装版本。 项目集成步骤️ 目录结构在bundles/目录下创建新的模块atomgitProfile/bundles/ └── atomgitProfile/ ├── api.ts # API 接口定义和请求函数 ├── hooks.ts # 自定义 Hook数据获取逻辑 ├── screen.tsx # UI 组件用户信息展示 └── index.ts # 模块导出 集成到主应用更新bundles/tabs.ts添加新的 Tab 项更新App.tsx扩展 TabKey 类型 代码实现详解1️⃣ API 接口层 (api.ts)✍️ 类型定义exportinterfaceAtomGitUser{id:number;login:string;name:string;email?:string;avatar_url?:string;bio?:string;blog?:string;company?:string;location?:string;public_repos?:number;public_gists?:number;followers?:number;following?:number;created_at?:string;updated_at?:string;} 设计要点使用?标记可选字段因为 API 可能不返回所有字段明确的类型定义有助于 TypeScript 类型检查和 IDE 自动补全 请求函数实现importaxios,{AxiosResponse}fromaxios;exportasyncfunctionfetchAtomGitUser(username:stringCodexBai):PromiseAtomGitUser{try{consturlhttps://api.atomgit.com/api/v5/users/${username};constresponse:AxiosResponseAtomGitUserawaitaxios.get(url,{timeout:10000,// 10秒超时headers:{Accept:application/json,User-Agent:DailyHotBundle/1.0,},});returnresponse.data;}catch(error){// 错误处理逻辑见下文}} 关键配置说明timeout: 设置请求超时时间为 10 秒避免长时间等待headers:Accept: 指定期望的响应格式User-Agent: 标识客户端应用类型泛型:AxiosResponseAtomGitUser确保响应数据的类型安全2️⃣ 错误处理详解Axios 的错误处理比fetch更加完善catch(error){if(axios.isAxiosError(error)){// Axios 错误网络错误、HTTP 错误等if(error.response){// 服务器返回了错误状态码4xx, 5xxthrownewError(请求失败:${error.response.status}-${error.response.statusText});}elseif(error.request){// 请求已发出但没有收到响应网络问题thrownewError(网络请求失败请检查网络连接);}else{// 请求配置错误thrownewError(请求配置错误:${error.message});}}else{// 非 Axios 错误thrownewError(未知错误:${String(error)});}} 错误类型说明错误类型触发条件处理方式error.response服务器返回 4xx/5xx显示 HTTP 状态码和错误信息error.request网络连接失败提示用户检查网络其他错误配置错误等显示通用错误信息3️⃣ 自定义 Hook (hooks.ts) 实现数据获取逻辑import{useEffect,useState}fromreact;import{fetchAtomGitUser,AtomGitUser}from./api;exportfunctionuseAtomGitUser(username:stringCodexBai){const[data,setData]useStateAtomGitUser|null(null);const[loading,setLoading]useStateboolean(false);const[error,setError]useStatestring|null(null);constfetchDataasync(){letmountedtrue;setLoading(true);setError(null);try{constuserDataawaitfetchAtomGitUser(username);if(mounted){setData(userData);}}catch(e){if(mounted){setError(String(einstanceofError?e.message:e));}}finally{if(mounted){setLoading(false);}}};useEffect((){fetchData();return(){// 清理函数防止组件卸载后更新状态};},[username]);return{data,loading,error,refetch:fetchData};} 设计要点状态管理data: 存储用户数据loading: 加载状态error: 错误信息内存泄漏防护使用mounted标志防止组件卸载后更新状态在useEffect的清理函数中重置标志暴露 refetch 方法允许外部手动触发数据刷新支持下拉刷新等交互4️⃣ UI 组件实现 (screen.tsx)⭐ 核心功能加载状态展示错误处理与重试用户信息展示下拉刷新 关键代码片段exportfunctionAtomGitProfileScreen(){const{data,loading,error,refetch}useAtomGitUser(CodexBai);const[refreshing,setRefreshing]React.useState(false);constonRefreshReact.useCallback(async(){setRefreshing(true);awaitrefetch();setRefreshing(false);},[refetch]);// 加载中状态if(loading!data){return(View style{styles.centerContainer}ActivityIndicator sizelargecolor#007AFF/Text style{styles.loadingText}加载中.../Text/View);}// 错误状态if(error){return(ScrollView contentContainerStyle{styles.centerContainer}refreshControl{RefreshControl refreshing{refreshing}onRefresh{onRefresh}/}Text style{styles.errorText}❌ 加载失败/TextText style{styles.errorDetail}{error}/TextPressable style{styles.retryButton}onPress{onRefresh}Text style{styles.retryButtonText}重试/Text/Pressable/ScrollView);}// 数据展示return(ScrollView style{styles.container}refreshControl{RefreshControl refreshing{refreshing}onRefresh{onRefresh}/}{/* 用户信息展示 */}/ScrollView);} 错误处理与异常管理 网络错误处理// 在 api.ts 中catch(error){if(axios.isAxiosError(error)){if(error.codeECONNABORTED){thrownewError(请求超时请稍后重试);}elseif(error.codeENOTFOUND||error.codeECONNREFUSED){thrownewError(无法连接到服务器请检查网络);}// ... 其他错误处理}} HTTP 状态码处理if(error.response){switch(error.response.status){case404:thrownewError(用户不存在);case403:thrownewError(访问被拒绝);case500:thrownewError(服务器错误请稍后重试);default:thrownewError(请求失败:${error.response.status});}} 用户友好的错误提示在 UI 层展示错误时使用友好的提示信息Text style{styles.errorText}❌ 加载失败/TextText style{styles.errorDetail}{error}/TextPressable style{styles.retryButton}onPress{onRefresh}Text style{styles.retryButtonText}重试/Text/Pressable 自定义 Hook 封装 Hook 设计模式自定义 Hook 的优势逻辑复用: 多个组件可以共享数据获取逻辑关注点分离: UI 组件专注于展示Hook 处理数据逻辑易于测试: 可以单独测试 Hook 逻辑➕ 扩展功能可以进一步扩展 Hook添加更多功能exportfunctionuseAtomGitUser(username:stringCodexBai){// ... 基础实现// 添加缓存机制const[cache,setCache]useStateMapstring,AtomGitUser(newMap());// 添加重试机制constretryasync(maxRetries3){for(leti0;imaxRetries;i){try{returnawaitfetchAtomGitUser(username);}catch(e){if(imaxRetries-1)throwe;awaitnewPromise(resolvesetTimeout(resolve,1000*(i1)));}}};return{data,loading,error,refetch,retry};} UI 组件实现 组件结构AtomGitProfileScreen ├── 加载状态 (ActivityIndicator) ├── 错误状态 (错误信息 重试按钮) └── 数据展示 ├── 头部 (头像 姓名 简介) ├── 统计信息 (仓库数、粉丝数、关注数) └── 详细信息 (公司、位置、博客等) 样式设计要点卡片式布局: 使用白色背景和阴影效果响应式设计: 适配不同屏幕尺寸加载状态: 清晰的加载指示器错误处理: 友好的错误提示和重试按钮 最佳实践与优化建议⚙️ Axios 实例配置创建 Axios 实例统一配置// utils/axiosInstance.tsimportaxiosfromaxios;constaxiosInstanceaxios.create({baseURL:https://api.AtomGit.com/api/v5,timeout:10000,headers:{Accept:application/json,User-Agent:DailyHotBundle/1.0,},});// 请求拦截器axiosInstance.interceptors.request.use((config){// 可以在这里添加 token 等returnconfig;},(error){returnPromise.reject(error);});// 响应拦截器axiosInstance.interceptors.response.use((response){returnresponse;},(error){// 统一错误处理returnPromise.reject(error);});exportdefaultaxiosInstance;⛔ 请求取消处理组件卸载时的请求取消useEffect((){constcancelTokenSourceaxios.CancelToken.source();fetchAtomGitUser(username,{cancelToken:cancelTokenSource.token}).then(setData).catch(setError);return(){cancelTokenSource.cancel(Component unmounted);};},[username]); 请求重试机制实现自动重试asyncfunctionfetchWithRetry(url:string,retries3){for(leti0;iretries;i){try{returnawaitaxios.get(url);}catch(error){if(iretries-1)throwerror;awaitnewPromise(resolvesetTimeout(resolve,1000*(i1)));}}}️ 缓存策略实现简单的内存缓存constcachenewMapstring,{data:AtomGitUser;timestamp:number}();constCACHE_DURATION5*60*1000;// 5分钟exportasyncfunctionfetchAtomGitUser(username:string):PromiseAtomGitUser{constcachedcache.get(username);if(cachedDate.now()-cached.timestampCACHE_DURATION){returncached.data;}constdataawaitaxios.get(/users/${username});cache.set(username,{data,timestamp:Date.now()});returndata;} TypeScript 类型安全充分利用 TypeScript 类型// 定义响应类型interfaceApiResponseT{data:T;status:number;message?:string;}// 使用泛型asyncfunctionfetchDataT(url:string):PromiseT{constresponseawaitaxios.getApiResponseT(url);returnresponse.data.data;}✅ 测试与验证 功能测试✅ 正常加载用户信息✅ 网络错误处理✅ 超时处理✅ 下拉刷新✅ 错误重试 边界情况测试✅ 用户不存在404✅ 网络断开✅ 服务器错误500✅ 组件卸载时的内存泄漏▶️ 运行验证# Androidnpmrun android# iOSnpmrun ios# 开源鸿蒙npmrun harmony 5. 将新的bundle.harmony.js文件拷贝到开源鸿蒙壳工程资源目录rawfile中替换已有的bundle.harmony.js。▶️ 6. 运行应用❓ 常见问题与解决方案❓ Q1: Axios 在 React Native 中无法使用A: React Native 0.72 已经内置了网络请求支持Axios 可以直接使用。如果遇到问题检查网络权限配置Android:AndroidManifest.xmliOS 网络安全配置iOS 9 需要 HTTPS开源鸿蒙需要在module.json5配置文件中配置网络权限❓ Q2: 如何处理 CORS 错误A: React Native 不受浏览器 CORS 限制但如果 API 服务器有 CORS 限制需要联系后端开发者配置 CORS或使用代理服务器❓ Q3: 请求超时如何设置A: 在 Axios 配置中设置timeoutaxios.get(url,{timeout:10000,// 10秒});❓ Q4: 如何取消正在进行的请求A: 使用CancelToken或AbortControllerconstsourceaxios.CancelToken.source();axios.get(url,{cancelToken:source.token});source.cancel(Operation canceled);❓ Q5: 如何处理并发请求A: 使用Promise.all或axios.allconst[user1,user2]awaitPromise.all([fetchAtomGitUser(user1),fetchAtomGitUser(user2),]); 总结 核心收获Axios 集成: 成功在 React Native 项目中集成 Axios实现了更强大的网络请求功能错误处理: 完善的错误处理机制提升用户体验代码组织: 清晰的分层架构API → Hook → UI易于维护和扩展TypeScript: 充分利用类型系统提高代码质量和开发效率️ 项目结构bundles/atomgitProfile/ ├── api.ts # API 接口层类型定义 请求函数 ├── hooks.ts # 数据层自定义 Hook ├── screen.tsx # UI 层用户界面 └── index.ts # 导出层模块导出 技术栈React Native 0.72.5: 跨平台框架TypeScript 4.8.4: 类型安全Axios 1.6.7: HTTP 客户端开源鸿蒙适配: 支持鸿蒙平台 参考资源Axios 官方文档React Native 网络文档TypeScript 官方文档AtomGit API 文档欢迎加入开源鸿蒙跨平台社区