🚀【RN鸿蒙教学|第3课时】集成网络请求能力(原生API+Axios)+ 数据解析与列表渲染
适配版本 :RN 0.72.7 + OpenHarmony SDK 8.0 + Axios 0.27.2
学习时长 :90分钟
难度等级:⭐⭐(入门→进阶)
📋 目录
哈喽大家好~ 欢迎来到React Native(RN)兼容开源鸿蒙(OpenHarmony)跨平台开发系列教学第3课时!🌐
前两课时我们已经完成了开发环境搭建、Git版本管理进阶,以及RN鸿蒙工程的基础配置,在上一课时末尾,我们还提前为工程添加了网络权限,为今天的核心内容------网络请求能力集成做好了铺垫。
本课时作为核心功能开发的第一节课,核心目标是帮大家掌握RN鸿蒙工程网络请求的两种实现方式(原生API+Axios三方库),搞定数据解析、异常处理,以及基础列表渲染,同时巩固Git代码提交规范,为下课时的列表交互(上拉加载/下拉刷新)筑牢基础。
🎯 适合人群 & 课时目标
适合人群
已完成前两课时实操,掌握Git分支管理、RN鸿蒙工程基础配置,想要学习网络请求集成的开发者
课时目标(90分钟达成)
- 熟练掌握鸿蒙网络权限的详细配置规范,理解权限生效逻辑,避免权限失效问题;
- 掌握RN原生网络请求API适配鸿蒙的用法,能独立完成简单GET/POST请求;
- 集成Axios三方库(RN鸿蒙适配版),掌握其配置、请求拦截、响应拦截用法;
- 完成网络请求返回数据的解析,实现基础列表渲染,处理空数据/异常数据兜底;
- 排查网络请求常见问题(超时、解析失败、权限失效),并完成代码规范提交。
🔧 一、课前准备(5分钟)
提前做好以下准备,确保课时内高效实操,避免卡顿,衔接前两课时内容:
-
✅ 确认前两课时创建的RN鸿蒙工程(rnHarmonyDemo)可正常运行,多终端(模拟器/真机/开发板)调试正常;
-
✅ 切换到规范分支(推荐新建
feature-network分支,贴合分支规范):bash# 从feature-init-optimize分支创建新功能分支 git checkout feature-init-optimize git checkout -b feature-network # 验证当前分支(可选) git branch -
✅ 检查RN版本(避免版本冲突):
bash# 查看RN版本 react-native --version # 确保输出包含 0.72.7 -
✅ 预习Axios基础用法(GET/POST请求、拦截器),记录预习中不懂的疑问(课时末尾统一答疑);
-
✅ 确认网络通畅,本节课提供免费测试接口(无需自建):
- GET请求(用户列表):
https://jsonplaceholder.typicode.com/users(返回10条用户数据) - POST请求(测试):
https://jsonplaceholder.typicode.com/posts
- GET请求(用户列表):
-
✅ 打开DevEco Studio、VScode(加载RN工程)、Git Bash,确认所有工具可正常使用。
⚠️ 关键注意:
- 重点确认
module.json5中的网络权限(ohos.permission.INTERNET)已正确配置,若未配置或配置错误,会导致网络请求失败;- 确保RN版本为0.72.7,避免与Axios版本冲突;
- 鸿蒙终端禁止HTTP明文请求,所有测试接口均使用HTTPS。
📚 二、核心知识点讲解(15分钟)
2.1 鸿蒙网络权限详细配置规范(重点⭐)
上一课时我们只是简单添加了网络权限,但很多新手会遇到"权限添加了,却无法正常请求"的问题,本节课详细讲解权限配置逻辑和生效条件:
- 📍 权限声明位置:
必须在ohos/main_pages/module.json5文件的"abilities"数组中配置(单个Ability配置),或在config.json中配置(全局配置),优先单个Ability配置,精准控制权限范围; - ✅ 权限生效条件(缺一不可):
① 配置格式正确(JSON语法无错误,逗号/引号配对,新手建议用JSON校验工具检查);
② 工程重新编译运行(权限修改后,需重启工程才能生效,热重载不生效);
③ 真机需手动授予网络权限(部分鸿蒙真机默认拒绝第三方应用网络权限); - 📝 补充说明:
鸿蒙网络权限分为"普通权限"和"敏感权限",INTERNET属于普通权限,无需用户手动授权(部分真机例外),配置后即可生效;敏感权限(如定位、存储)后续课时讲解。
2.2 RN原生网络请求API与鸿蒙适配差异
RN原生提供了Fetch API和XMLHttpRequest两种网络请求方式,适配鸿蒙时需注意以下差异,避免请求失败:
| 请求方式 | 鸿蒙适配要点 | 适用场景 |
|---|---|---|
| Fetch API | 无需大幅修改,注意请求头格式、HTTPS协议 | 简单请求(GET/POST),RN官方推荐 |
| XMLHttpRequest | 需配置Content-Type请求头,避免数据格式不兼容 |
传统项目迁移,需兼容老代码 |
- ⚡ 核心差异:RN原生请求在鸿蒙终端运行时,需遵循鸿蒙的网络安全规范,禁止明文请求(http),优先使用https请求(本节课测试接口为https,避免踩坑)。
2.3 Axios三方库的鸿蒙适配要点
Axios是RN生态中最常用的HTTP请求库,支持拦截器、请求取消、响应转换等功能,适配鸿蒙时重点关注以下要点:
- 📌 版本选择:必须使用适配鸿蒙的Axios版本(推荐
0.27.2版本,亲测兼容RN 0.72.7 + 鸿蒙SDK 8.0),避免使用最新版本(可能存在适配问题); - 🧩 集成逻辑:通过npm安装后,需进行简单配置(请求头、超时时间),无需额外修改源码,鸿蒙适配层会自动处理请求转换;
- 🛡️ 拦截器核心价值:
- 请求拦截器:统一添加请求头(如Token、App版本)、设置全局加载状态,减少重复代码;
- 响应拦截器:统一处理响应数据(直接返回解析后的JSON)、拦截错误(如超时、404),提升开发效率;
- ⏱️ 开发板适配:Axios在鸿蒙开发板上运行时,需优化超时时间(建议设置为10000ms+),避免开发板网络不稳定导致请求失败。
2.4 数据解析与列表渲染核心逻辑
网络请求返回的数据多为JSON格式,需解析后才能用于页面渲染,本节课实现基础列表渲染,为下课时进阶做铺垫:
- 📊 数据解析:将JSON字符串转换为RN可识别的对象/数组,必须添加格式校验(如判断是否为数组),处理解析失败的异常;
- 📜 列表渲染:使用RN原生
FlatList组件(适配鸿蒙),比map循环更高效(支持懒加载、复用列表项),无需额外三方库; - 🎨 兜底处理:实现3种状态兜底------加载中、空数据(请求成功但无数据)、异常数据(解析失败/请求失败),避免白屏,提升用户体验。
💻 三、实操步骤(50分钟,重点环节)
本环节全程实操,从权限验证、原生API请求,到Axios集成、数据解析、列表渲染,一步步推进,每一步都有验证环节和代码提交,贴合开发实际场景。
3.1 步骤1:验证并优化鸿蒙网络权限配置(5分钟)
先确认上课时添加的网络权限生效,避免后续请求失败,同时优化权限配置,确保适配多终端。
操作步骤
-
打开VScode,定位到工程目录下的
ohos/main_pages/module.json5文件; -
优化权限配置(确保格式正确,添加权限说明),修改
"abilities"数组中的配置:json"requestPermissions": [ { "name": "ohos.permission.INTERNET", "reason": "$string:internet_permission_reason", // 支持国际化,新手可直接写文字 "usedScene": { "ability": ["MainAbility"], "when": "always" } } ]💡 新手简化版(直接生效,无需配置国际化):
json"requestPermissions": [ { "name": "ohos.permission.INTERNET", "reason": "应用需要访问网络,获取用户列表数据", "usedScene": { "ability": ["MainAbility"], "when": "always" } } ] -
保存文件,重启工程(必须重启,热重载不生效):
bashreact-native run-ohos --emulator -
验证权限生效:工程启动后,无"网络权限未配置"相关报错即可;
-
Git规范提交:
bashgit add . git commit -m "feat: 优化网络权限配置,添加权限说明"
📌 小提示:若修改
module.json5后工程启动失败,大概率是JSON语法错误(如少逗号、引号不配对),可复制内容到JSON校验工具检查。
3.2 步骤2:使用RN原生Fetch API实现GET请求(10分钟)
先实操RN原生请求方式,理解鸿蒙适配逻辑,再集成Axios,循序渐进,避免直接集成三方库踩坑。
完整代码示例(App.js)
javascript
import React, { useState, useEffect } from 'react';
import { View, Text, StyleSheet } from 'react-native';
const App = () => {
// 状态管理:用户列表、加载状态、异常信息
const [userList, setUserList] = useState([]); // 存储用户列表数据
const [loading, setLoading] = useState(true); // 加载状态
const [error, setError] = useState(''); // 异常信息
// 生命周期:组件挂载后发起请求(空依赖数组仅执行一次)
useEffect(() => {
// 封装请求函数(async/await 写法,比链式调用更易读)
const fetchUserList = async () => {
try {
// 发起GET请求
const response = await fetch('https://jsonplaceholder.typicode.com/users', {
method: 'GET',
headers: {
'Content-Type': 'application/json' // 声明请求体格式
}
});
// 解析JSON数据(必须判断响应是否成功)
if (!response.ok) {
throw new Error(`请求失败:${response.status}`);
}
const data = await response.json();
// 更新状态
setUserList(data);
setLoading(false);
} catch (err) {
// 捕获异常,更新状态
setError('请求失败,请重试');
setLoading(false);
console.log('Fetch请求异常:', err); // 控制台打印异常,方便调试
}
};
// 执行请求函数
fetchUserList();
}, []);
// 页面渲染(条件渲染:加载中→异常→数据列表)
return (
<View style={styles.container}>
{loading ? (
<Text style={styles.loadingText}>加载中...</Text>
) : error ? (
<Text style={styles.errorText}>{error}</Text>
) : (
<View style={styles.listContainer}>
{userList.map(item => (
<View key={item.id} style={styles.itemCard}>
<Text style={styles.itemName}>{item.name}</Text>
<Text style={styles.itemEmail}>{item.email}</Text>
</View>
))}
</View>
)}
</View>
);
};
// 样式配置(RN StyleSheet,类似CSS)
const styles = StyleSheet.create({
container: {
flex: 1, // 占满整个屏幕
padding: 15,
backgroundColor: '#fff'
},
loadingText: {
flex: 1,
textAlign: 'center',
textAlignVertical: 'center', // 垂直居中(RN特有)
fontSize: 16
},
errorText: {
flex: 1,
textAlign: 'center',
textAlignVertical: 'center',
fontSize: 16,
color: '#ff4444' // 红色提示
},
listContainer: {
flex: 1
},
itemCard: {
padding: 12,
borderBottomWidth: 1, // 底部边框
borderBottomColor: '#eeeeee',
marginBottom: 8
},
itemName: {
fontSize: 16,
fontWeight: '600', // 半粗体
color: '#333'
},
itemEmail: {
fontSize: 14,
color: '#666',
marginTop: 4
}
});
export default App;
验证请求效果
-
启动模拟器,运行工程:
bashreact-native run-ohos --emulator -
打开调试控制台(Ctrl+M,选择Debug),查看是否有请求异常日志;
-
✅ 验证标准:
- 请求成功:页面显示10条用户数据(名称+邮箱);
- 请求失败:页面显示"请求失败,请重试",控制台输出异常日志。
📌 小提示:若请求失败,优先检查:① 网络权限配置 ② 接口是否为HTTPS ③ 网络是否通畅。
3.3 步骤3:集成Axios三方库,实现请求优化(15分钟)
原生Fetch API功能有限(无拦截器、无超时配置),实际开发中常用Axios,重点实操Axios的安装、配置、拦截器用法,适配鸿蒙终端。
1. 安装适配鸿蒙的Axios版本
bash
# 进入工程根目录(确保路径正确)
cd rnHarmonyDemo
# 安装指定版本(兼容RN 0.72.7 + 鸿蒙SDK 8.0)
npm install axios@0.27.2 --save
2. 验证安装
- 查看
package.json文件,dependencies中需包含:"axios": "^0.27.2"; - 查看工程目录下的
node_modules文件夹,确认存在axios目录。
📌 小提示:若安装失败,可执行
npm cache clean --force清理缓存后重新安装。
3. 配置Axios(全局配置,方便后续复用)
① 创建目录结构(按模块化规范组织代码):
bash
# mac/Linux 系统
mkdir -p src/api
# Windows CMD 系统
mkdir src\api
② 在src/api目录下新建request.js文件,添加以下配置(核心:拦截器+全局配置):
javascript
import axios from 'axios';
// 创建Axios实例(全局配置)
const service = axios.create({
baseURL: 'https://jsonplaceholder.typicode.com', // 基础请求路径(后续请求只需传相对路径)
timeout: 10000, // 超时时间(开发板建议设置为15000ms)
headers: {
'Content-Type': 'application/json;charset=utf-8' // 统一请求头格式
}
});
// ✨ 请求拦截器:请求发送前的统一处理
service.interceptors.request.use(
(config) => {
// 示例:添加Token(实际项目中可从本地存储获取)
// const token = localStorage.getItem('token');
// if (token) {
// config.headers.Authorization = `Bearer ${token}`;
// }
// 打印请求参数,方便调试
console.log('【请求参数】', config);
return config;
},
(error) => {
// 请求配置错误处理
console.error('【请求拦截器异常】', error);
return Promise.reject(error);
}
);
// ✨ 响应拦截器:响应返回后的统一处理
service.interceptors.response.use(
(response) => {
// 直接返回解析后的JSON数据,简化业务层代码
console.log('【响应数据】', response.data);
return response.data;
},
(error) => {
// 统一错误处理(分类提示,更友好)
let errorMsg = '网络请求失败';
if (error.response) {
// 服务器返回错误(4xx/5xx)
errorMsg = `请求失败:${error.response.status} ${error.response.statusText}`;
} else if (error.request) {
// 请求已发送,但无响应(超时/断网)
errorMsg = '网络异常,请检查网络连接';
} else {
// 请求配置错误
errorMsg = `请求配置错误:${error.message}`;
}
// 打印错误日志,方便调试
console.error('【响应拦截器异常】', errorMsg);
// 返回标准化的错误信息
return Promise.reject(new Error(errorMsg));
}
);
// 导出配置好的Axios实例(供业务层调用)
export default service;
4. 使用Axios替换原生Fetch(修改App.js)
javascript
import React, { useState, useEffect } from 'react';
import { View, Text, StyleSheet } from 'react-native';
// 导入配置好的Axios实例(注意路径正确性)
import service from './src/api/request';
const App = () => {
const [userList, setUserList] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState('');
useEffect(() => {
// 使用Axios发起GET请求(代码更简洁)
const fetchUserList = async () => {
try {
setLoading(true);
// 基于baseURL,只需传相对路径(/users → https://jsonplaceholder.typicode.com/users)
const data = await service.get('/users');
setUserList(data);
setError(''); // 清空异常信息
} catch (err) {
// 捕获拦截器返回的标准化错误
setError(err.message);
setUserList([]); // 清空数据
} finally {
// 无论成功/失败,都结束加载状态
setLoading(false);
}
};
fetchUserList();
}, []);
// 页面渲染(与Fetch版本一致,无需修改)
return (
<View style={styles.container}>
{loading ? (
<Text style={styles.loadingText}>加载中...</Text>
) : error ? (
<Text style={styles.errorText}>{error}</Text>
) : (
<View style={styles.listContainer}>
{userList.map(item => (
<View key={item.id} style={styles.itemCard}>
<Text style={styles.itemName}>{item.name}</Text>
<Text style={styles.itemEmail}>{item.email}</Text>
</View>
))}
</View>
)}
</View>
);
};
// 样式配置(与之前一致,无需修改)
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 15,
backgroundColor: '#fff'
},
loadingText: {
flex: 1,
textAlign: 'center',
textAlignVertical: 'center',
fontSize: 16
},
errorText: {
flex: 1,
textAlign: 'center',
textAlignVertical: 'center',
fontSize: 16,
color: '#ff4444'
},
listContainer: {
flex: 1
},
itemCard: {
padding: 12,
borderBottomWidth: 1,
borderBottomColor: '#eeeeee',
marginBottom: 8
},
itemName: {
fontSize: 16,
fontWeight: '600',
color: '#333'
},
itemEmail: {
fontSize: 14,
color: '#666',
marginTop: 4
}
});
export default App;
5. 验证Axios请求
bash
# 重启工程(加载新安装的Axios依赖)
react-native run-ohos --emulator
✅ 验证标准:
- 拦截器生效:控制台输出"【请求参数】"和"【响应数据】"日志;
- 请求成功:页面正常显示用户列表;
- 断网测试:页面显示"网络异常,请检查网络连接"(拦截器统一处理的错误信息)。
3.4 步骤4:数据解析与基础列表渲染(15分钟)
请求成功后,使用RN原生FlatList组件优化列表渲染(比map循环更高效,支持懒加载),添加完整的兜底逻辑(加载中/异常/空数据)。
完整优化版App.js(FlatList实现)
javascript
import React, { useState, useEffect } from 'react';
import { View, Text, StyleSheet, FlatList, TouchableOpacity } from 'react-native';
import service from './src/api/request';
const App = () => {
const [userList, setUserList] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState('');
useEffect(() => {
const fetchUserList = async () => {
try {
setLoading(true);
const data = await service.get('/users');
// 🔍 数据解析校验(关键:避免非数组数据导致渲染异常)
if (Array.isArray(data)) {
setUserList(data);
setError('');
} else {
setUserList([]);
setError('数据格式错误,非数组类型');
}
} catch (err) {
setError(err.message);
setUserList([]);
} finally {
setLoading(false);
}
};
fetchUserList();
}, []);
// 🖱️ 列表项点击事件(新手拓展:后续可跳转详情页)
const handleItemClick = (item) => {
console.log('点击了用户:', item.id, item.name);
alert(`你点击了 ${item.name}(ID:${item.id})`);
};
// 🎨 列表项渲染函数(抽离成独立函数,代码更清晰)
const renderUserItem = ({ item }) => (
<TouchableOpacity
style={styles.itemCard}
onPress={() => handleItemClick(item)} // 添加点击事件
activeOpacity={0.9} // 点击透明度效果(RN特有)
>
<Text style={styles.itemName}>{item.name}</Text>
<Text style={styles.itemEmail}>📧 {item.email}</Text>
<Text style={styles.itemPhone}>📱 {item.phone}</Text>
</TouchableOpacity>
);
// 页面渲染(完整的4种状态:加载中→异常→空数据→列表)
return (
<View style={styles.container}>
{loading ? (
<Text style={styles.loadingText}>加载中...</Text>
) : error ? (
<Text style={styles.errorText}>{error}</Text>
) : userList.length === 0 ? (
<Text style={styles.emptyText}>📭 暂无用户数据</Text>
) : (
<FlatList
data={userList} // 数据源(必须是数组)
keyExtractor={(item) => item.id.toString()} // 唯一Key(必须,避免警告)
renderItem={renderUserItem} // 列表项渲染函数
showsVerticalScrollIndicator={false} // 隐藏垂直滚动条(优化体验)
contentContainerStyle={styles.listContent} // 列表内边距
initialNumToRender={5} // 初始渲染5项(优化性能)
/>
)}
</View>
);
};
// 样式优化(适配多终端屏幕)
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
paddingHorizontal: 15, // 左右内边距(适配不同屏幕宽度)
paddingVertical: 10
},
loadingText: {
flex: 1,
textAlign: 'center',
textAlignVertical: 'center',
fontSize: 16,
color: '#666'
},
errorText: {
flex: 1,
textAlign: 'center',
textAlignVertical: 'center',
fontSize: 16,
color: '#ff4444'
},
emptyText: {
flex: 1,
textAlign: 'center',
textAlignVertical: 'center',
fontSize: 16,
color: '#999'
},
listContent: {
paddingVertical: 5 // 列表上下内边距
},
itemCard: {
padding: 15,
borderBottomWidth: 1,
borderBottomColor: '#f0f0f0',
marginBottom: 10,
borderRadius: 8, // 圆角效果
backgroundColor: '#fafafa'
},
itemName: {
fontSize: 17,
fontWeight: '600',
color: '#222'
},
itemEmail: {
fontSize: 14,
color: '#666',
marginTop: 5
},
itemPhone: {
fontSize: 14,
color: '#888',
marginTop: 3
}
});
export default App;
多终端验证
- 📱 模拟器验证:运行
react-native run-ohos --emulator,列表正常渲染,点击列表项弹出提示; - 🖥️ 真机验证:运行
react-native run-ohos --device,适配手机屏幕,无布局错乱; - 🔧 开发板验证:运行
react-native run-ohos --device [开发板ID],列表正常显示,点击事件生效。
✅ 兜底逻辑验证(必做):
- 断网测试:页面显示"网络异常,请检查网络连接";
- 接口返回空数组测试:修改
service.get('/users')为service.get('/empty'),页面显示"📭 暂无用户数据"; - 数据格式错误测试:修改接口返回非数组数据,页面显示"数据格式错误,非数组类型"。
3.5 步骤5:Git规范提交代码(5分钟)
完成所有实操后,按规范提交代码到远程feature分支,巩固Git用法。
bash
# 添加所有修改文件
git add .
# 规范提交(feat表示新增功能,描述清晰)
git commit -m "feat: 集成Axios与原生网络请求,实现用户列表渲染及兜底处理"
# 推送至远程feature-network分支
git push origin feature-network
✅ 验证:打开AtomGit/Gitee/GitHub仓库,查看feature-network分支的提交记录,确认代码推送成功。
📌 小提示:提交信息规范建议遵循Conventional Commits,如
feat(新增功能)、fix(修复bug)、docs(文档更新)等。
❌ 四、常见问题与解决方案(10分钟,新手必看)
本课时实操核心是网络请求与数据解析,新手容易在权限、三方库、请求异常、列表渲染环节踩坑,整理高频问题及解决方案:
🚫 问题1:网络请求失败,控制台提示「net::ERR_ACCESS_DENIED」
✅ 解决方案:
- 检查
module.json5中的网络权限配置,确保格式正确、权限名称(ohos.permission.INTERNET)无误; - 重启工程(权限修改后需重启生效,热重载不生效);
- 真机需手动授予网络权限(设置→应用→对应应用→权限→开启网络权限);
- 确认请求接口为HTTPS(鸿蒙禁止HTTP明文请求,可在
module.json5中配置例外,但不推荐)。
🚫 问题2:Axios安装后,运行工程报错「Cannot find module 'axios'」
✅ 解决方案:
-
确认Axios版本为0.27.2(
package.json中检查),避免版本不兼容; -
清理缓存并重新安装依赖:
bash# mac/Linux rm -rf node_modules package-lock.json # Windows # rmdir /s node_modules # del package-lock.json npm cache clean --force npm install -
检查
request.js中的导入路径是否正确(import axios from 'axios',无需加相对路径); -
检查App.js中导入
service的路径是否正确(如./src/api/request,注意./不能省略)。
🚫 问题3:请求成功,但数据解析失败,提示「Unexpected token < in JSON at position 0」
✅ 解决方案:
-
检查请求接口返回的数据格式,确保是JSON格式(本节课测试接口
https://jsonplaceholder.typicode.com/users无误); -
若接口返回HTML(如404页面),确认接口地址正确(如少写
/users); -
在响应拦截器中添加数据格式校验(推荐):
javascriptservice.interceptors.response.use( (response) => { // 校验响应数据格式 const contentType = response.headers['content-type']; if (!contentType || !contentType.includes('application/json')) { return Promise.reject(new Error('响应数据非JSON格式')); } return response.data; }, (error) => { /* 错误处理逻辑 */ } );
🚫 问题4:FlatList列表渲染无效果,控制台无异常
✅ 解决方案:
- 检查
FlatList的data属性是否为数组(通过console.log(userList)验证,确保不是undefined/null); - 确认
keyExtractor配置正确,每个列表项有唯一key(推荐用item.id.toString(),避免用索引); - 检查
FlatList的父容器是否有flex:1样式(如container的flex:1),避免列表被压缩无法显示; - 验证
renderItem函数是否正确接收item参数(需解构:({ item }),而非(item)); - 检查
userList是否为空数组(若为空,会显示空数据提示,而非列表)。
🚫 问题5:开发板上请求超时,模拟器/真机正常
✅ 解决方案:
-
优化Axios超时时间(开发板建议设置为15000ms):
javascriptconst service = axios.create({ timeout: 15000, // 延长超时时间 // 其他配置... }); -
检查开发板网络连接,确保与电脑在同一局域网(开发板需能访问外网);
-
替换为更稳定的测试接口(如
https://httpbin.org/get); -
关闭开发板的防火墙/代理(若有)。
🚫 问题6:列表项点击事件不生效
✅ 解决方案:
- 确保列表项使用
TouchableOpacity/TouchableHighlight等可点击组件包裹(View组件无点击事件); - 检查
onPress属性是否正确绑定(onPress={() => handleItemClick(item)},需用箭头函数传递参数); - 确保
TouchableOpacity的父容器无pointerEvents: 'none'样式(禁止点击)。
📝 五、课堂小结(5分钟)
本课时核心完成了RN鸿蒙工程网络请求能力的集成,衔接前两课时的基础配置,重点掌握4个核心要点:
- 鸿蒙网络权限的配置关键是「格式正确+重启生效」,真机需注意手动授予权限,这是网络请求成功的前提;
- RN原生Fetch API适配鸿蒙时,需注意请求头格式和HTTPS协议,Axios集成的关键是「版本适配(0.27.2)+ 拦截器配置」,拦截器可大幅减少重复代码;
- 数据解析必须添加格式校验(如
Array.isArray()),列表渲染优先使用FlatList组件,配合完整的状态兜底(加载中/异常/空数据),避免白屏; - 网络请求常见问题的排查思路:先查权限→再查接口(HTTPS/地址)→然后查代码(请求逻辑/解析逻辑)→最后查终端网络,循序渐进。
本课时实现的列表渲染是基础版本,下一节课我们将在此基础上,为列表添加上拉加载、下拉刷新功能,进一步完善列表交互体验,同时深入学习列表适配鸿蒙多终端的优化方法。
✅ 六、课后任务(必做)
任务1:复盘实操流程
独立完成「原生Fetch请求→Axios集成→FlatList列表渲染→兜底处理」全流程,熟练掌握Axios拦截器用法(尝试在请求拦截器中添加自定义请求头)。
任务2:优化列表交互与样式
- 优化列表样式,适配开发板/平板屏幕(使用
Dimensions获取屏幕宽度,动态设置列表项宽度); - 完善列表项点击事件:点击后跳转到新页面(可新建
UserDetail.js页面,显示用户完整信息)。
任务3:实现Axios POST请求
使用测试接口https://jsonplaceholder.typicode.com/posts发起POST请求,提交以下数据,并完成Git规范提交:
javascript
// 在App.js中添加POST请求函数
const sendPost = async () => {
try {
const postData = {
title: 'RN鸿蒙测试',
body: '这是Axios POST请求测试',
userId: 1
};
const res = await service.post('/posts', postData);
console.log('POST请求成功:', res);
alert('POST请求成功,返回ID:' + res.id);
} catch (err) {
alert('POST请求失败:' + err.message);
}
};
// 在页面中添加按钮触发POST请求
<View style={styles.btnContainer}>
<TouchableOpacity
style={styles.postBtn}
onPress={sendPost}
>
<Text style={styles.postBtnText}>发起POST请求</Text>
</TouchableOpacity>
</View>
// 添加按钮样式
btnContainer: {
padding: 10,
alignItems: 'center'
},
postBtn: {
backgroundColor: '#007bff',
padding: 10,
borderRadius: 6,
width: '80%'
},
postBtnText: {
color: '#fff',
textAlign: 'center',
fontSize: 16
}
任务4:整理笔记+预习
- 整理本课时遇到的问题及解决方案,形成笔记;
- 预习RN
FlatList组件的进阶用法:onEndReached(上拉加载更多)RefreshControl(下拉刷新)ItemSeparatorComponent(列表项分隔线)
🎯 核心要点总结
- 网络请求基础 :鸿蒙网络权限需配置在
module.json5中且重启生效,优先使用HTTPS接口,Axios选择0.27.2版本适配RN 0.72.7; - Axios核心优势:拦截器可统一处理请求头、错误信息,简化业务层代码,开发板需延长超时时间;
- 列表渲染最佳实践 :使用
FlatList替代map循环,添加加载中/异常/空数据兜底,列表项需配置唯一keyExtractor。
若你在实操过程中遇到网络请求、Axios集成、列表渲染相关的问题,欢迎在评论区留言,我会逐一解答~ 下一节课,我们继续深耕列表交互,一起搞定上拉加载和下拉刷新,让列表功能更完善!🚀
关注我,后续课时持续更新,从0到1掌握RN兼容鸿蒙跨平台开发,夯实每一个核心功能环节!
欢迎加入开源鸿蒙跨平台社区,https://openharmonycrossplatform.csdn.net