在 React Native App 开发中,列表渲染和网络请求是两个最基础、高频的能力。 本篇文章一次性带你走完完整流程:
- 使用
map遍历数组渲染列表,理解key的作用 - 启动本地 Node 后端 API(SQLite + Prisma,配套示例 JSON 返回样例,无需依赖外部在线接口服务)
- RN 使用原生
fetch请求后端接口,展示真实数据 - 踩坑:Android 模拟器、真机调试网络问题
一、基础:map 遍历渲染列表
在useState里定义的数据,在很多时候,都是读取的接口数据,然后遍历出来,显示到页面上。
没有学如何读取接口之前,可以先定义一点假数据,然后遍历一下试试。 开发 App 列表,我们经常会拿到后端返回的数组,然后循环渲染每一项。在 React / RN 中,标准写法就是数组的 .map()。
1.1 定义状态数组
用 useState 定义课程假数据,每个对象包含唯一 id 和课程名称。
<span>import</span> { <span>StyleSheet</span>, <span>Text</span>, <span>View</span> } <span>from</span> <span>'react-native'</span>;
<span>import</span> { useState } <span>from</span> <span>'react'</span>;
<span>export</span> <span>default</span> <span>function</span> <span>App</span>(<span></span>) {
<span>const</span> [courses, setCourses] = <span>useState</span>([
{ <span>id</span>: <span>1</span>, <span>name</span>: <span>'HTML'</span> },
{ <span>id</span>: <span>2</span>, <span>name</span>: <span>'CSS'</span> },
{ <span>id</span>: <span>3</span>, <span>name</span>: <span>'JavaScript'</span> },
{ <span>id</span>: <span>4</span>, <span>name</span>: <span>'React'</span> },
{ <span>id</span>: <span>5</span>, <span>name</span>: <span>'React Native'</span> },
{ <span>id</span>: <span>6</span>, <span>name</span>: <span>'Node.js'</span> },
{ <span>id</span>: <span>7</span>, <span>name</span>: <span>'Express'</span> },
{ <span>id</span>: <span>8</span>, <span>name</span>: <span>'MySQL'</span> },
{ <span>id</span>: <span>9</span>, <span>name</span>: <span>'Ruby On Rails'</span> },
{ <span>id</span>: <span>10</span>, <span>name</span>: <span>'Python'</span> },
{ <span>id</span>: <span>11</span>, <span>name</span>: <span>'Django'</span> },
{ <span>id</span>: <span>12</span>, <span>name</span>: <span>'C#'</span> },
]);
<span>return</span> (
<span><span><<span>View</span> <span>style</span>=<span>{styles.container}</span>></span>
{courses.map((course) => (
<span><<span>Text</span> <span>key</span>=<span>{course.id}</span>></span>
{course.name}
<span></<span>Text</span>></span>
))}
<span></<span>View</span>></span></span>
);
}
<span>const</span> styles = <span>StyleSheet</span>.<span>create</span>({
<span>container</span>: {
<span>flex</span>: <span>1</span>,
<span>backgroundColor</span>: <span>'#fff'</span>,
<span>alignItems</span>: <span>'center'</span>,
<span>justifyContent</span>: <span>'center'</span>,
},
});
1.2 核心要点
-
{}在 JSX 中用来嵌入 JS 表达式 -
.map()遍历数组,返回新的 JSX 元素数组,完成渲染 -
key 属性必须加
- key 作用:帮助 React 识别列表每一个元素,高效做 Diff 更新
- 要求:列表内唯一,优先使用后端返回 id,不要直接用数组下标(简单演示可以,但生产不推荐)
- 不写 key:控制台会抛出警告,列表更新时容易出现渲染错乱
现在我们渲染的是前端写死的假数据,接下来搭建后端,拿到真实接口数据。
二、搭建并启动本地后端 API 服务
我们使用 Node + Prisma + SQLite 作为本地后端,SQLite 是文件型数据库,不用安装 MySQL、Docker,开箱即用。
2.1 后端源码准备
下载示例后端源码包 zxj‑api 解压。
建议把后端项目
zxj‑api和 RN 项目zxj‑app放在同一级目录。
2.2 安装依赖(可选切换淘宝镜像)
为了防止由于网络问题,导致依赖包安装出错。未使用 npm 中国镜像的,请先切换到中国镜像。
<span># 可选:安装 nrm 切换淘宝镜像,解决国内 npm 下载慢</span>
npm i -g nrm
nrm use taobao
<span># 进入后端项目目录</span>
<span>cd</span> zxj-api
<span># 安装项目依赖</span>
npm i
2.3 初始化 Prisma 数据库客户端
npx prisma generate
2.4 启动后端服务
npm start
启动成功后,本地接口基础地址:http://localhost:3000
⚠️ 启动后端的终端窗口不要关闭,关闭接口服务就停止了。
2.5 数据库管理
项目使用 SQLite,数据库文件:prisma/dev.db接口项目的数据库,我使用了SQLite来开发。它其实就是一个本地文件。 用这种数据库,就不需要大家去安装配置Docker,搭建MySQL运行环境,导入数据库了。
数据库的管理,有两种方法:
- **Prisma Studio(网页版)**新开终端,进入 zxj‑api:
<span># 默认端口</span>
npx prisma studio
<span># 如果端口5555冲突(Android模拟器占用),更换端口</span>
npx prisma studio -p 5556
浏览器自动打开可视化数据库面板,可以直接增删改查。
- Navicat 连接 SQLite
官方免费版本下载地址:www.navicat.com.cn/download/na…Navicat Premium Lite(免费版)新建 SQLite 连接,选中项目内 prisma/dev.db 文件即可。
2.6 接口说明 & 返回 JSON 样例
① 首页接口 GET /
- 请求参数:无
- 响应格式:
200 application/json返回包含三类课程数组:recommendedCourses(推荐课程)、likesCourses(热门课程)、introductoryCourses(入门课程)。
<span>{</span>
<span>"status"</span><span>:</span> <span><span>true</span></span><span>,</span>
<span>"message"</span><span>:</span> <span>"查询首页数据成功。"</span><span>,</span>
<span>"data"</span><span>:</span> <span>{</span>
<span>"recommendedCourses"</span><span>:</span> <span>[</span>
<span>{</span>
<span>"id"</span><span>:</span> <span>10</span><span>,</span>
<span>"name"</span><span>:</span> <span>"React Native + Expo 项目实战"</span><span>,</span>
<span>"image"</span><span>:</span> <span>"http://localhost:3000/uploads/images/demo.png"</span><span>,</span>
<span>"recommended"</span><span>:</span> <span><span>true</span></span><span>,</span>
<span>"introductory"</span><span>:</span> <span><span>false</span></span><span>,</span>
<span>"likesCount"</span><span>:</span> <span>0</span><span>,</span>
<span>"chaptersCount"</span><span>:</span> <span>0</span><span>,</span>
<span>"category"</span><span>:</span> <span>{</span><span>"id"</span><span>:</span><span>3</span><span>,</span><span>"name"</span><span>:</span><span>"移动端开发"</span><span>}</span>
<span>}</span>
<span>]</span><span>,</span>
<span>"likesCourses"</span><span>:</span> <span>[</span><span>]</span><span>,</span>
<span>"introductoryCourses"</span><span>:</span> <span>[</span><span>]</span>
<span>}</span>
<span>}</span>
② 搜索接口 GET /search
- Query 参数:
q(可选,课程名关键词,不传返回全部课程) - 浏览器直接访问测试:
http://localhost:3000/search - 返回结构:
{status: true, data: {courses: [...]}}
三、RN 使用 Fetch 请求后端接口
React Native 内置 Fetch API,不需要额外安装 axios 等网络库,就可以发起网络请求。
3.1 完整代码
<span>import</span> { <span>Button</span>, <span>StyleSheet</span>, <span>Text</span>, <span>View</span> } <span>from</span> <span>'react-native'</span>;
<span>import</span> { useState } <span>from</span> <span>'react'</span>;
<span>export</span> <span>default</span> <span>function</span> <span>App</span>(<span></span>) {
<span>// 初始为空数组,等待接口填充数据</span>
<span>const</span> [courses, setCourses] = <span>useState</span>([]);
<span>/**
* 获取课程接口数据
* <span>@returns</span> {<span>Promise<void></span>}
*/</span>
<span>const</span> <span>fetchData</span> = <span>async</span> (<span></span>) => {
<span>// ⚠️ Android模拟器 / 真机不能写 localhost,需要替换成电脑局域网IP</span>
<span>const</span> res = <span>await</span> <span>fetch</span>(<span>'http://localhost:3000/search'</span>);
<span>const</span> { data } = <span>await</span> res.<span>json</span>();
<span>setCourses</span>(data.<span>courses</span>);
<span>console</span>.<span>log</span>(<span>'获取到的数据是:'</span>, data.<span>courses</span>);
};
<span>return</span> (
<span><span><<span>View</span> <span>style</span>=<span>{styles.container}</span>></span>
{courses.map((course) => (
<span><<span>Text</span> <span>key</span>=<span>{course.id}</span>></span>
{course.name}
<span></<span>Text</span>></span>
))}
<span><<span>Button</span> <span>title</span>=<span>'获取课程'</span> <span>onPress</span>=<span>{fetchData}/</span>></span>
<span></<span>View</span>></span></span>
);
}
<span>const</span> styles = <span>StyleSheet</span>.<span>create</span>({
<span>container</span>: {
<span>flex</span>: <span>1</span>,
<span>backgroundColor</span>: <span>'#fff'</span>,
<span>alignItems</span>: <span>'center'</span>,
<span>justifyContent</span>: <span>'center'</span>,
},
});
- 函数的名字,叫做
fetchData。 - 接口读取,是一个异步请求,所以别忘了要加上
async。 - 里面就用
fetch来请求接口地址了,当然,前面别忘记了加上await。 - 获取到的数据是
JSON格式的,这里要用.json()来解析一下。 - 大家观察返回的数据格式
{ data: { courses: [...] } },它里面是有一层data,在data里面才是最后的课程数据。 - 所以,可以给
data加了一个大括号,直接将data解构出来。 - 最后将获取到的
data.courses课程数据,使用setCourses设置到课程状态里。
四、重点踩坑:Android 模拟器 & 真机网络
这是 RN 本地开发最容易踩的坑!
4.1 Android 模拟器
模拟器里的 localhost 指向模拟器本身,不是你的电脑,接口访问失败。 ✅ 解决方案:把地址改成电脑局域网 IP
<span># Windows 查看局域网IPv4</span>
ipconfig | findstr <span>"IPv4"</span>
<span># macOS</span>
ifconfig | grep <span>"inet "</span> | grep -v 127.0.0.1
示例,拿到 IP:192.168.31.100
<span>const</span> res = <span>await</span> <span>fetch</span>(<span>'http://192.168.31.100:3000/search'</span>);
4.2 手机真机扫码预览
手机和电脑必须连同一个路由器 / Wi‑Fi。 同样不能使用 localhost,替换为电脑局域网 IP。 修改代码后,摇一摇手机,选择 Reload 重新加载 App。
Windows 电脑访问仍然失败:检查并临时关闭防火墙,手机浏览器先访问
http://你的IP:3000验证接口通不通。 IP 会随网络重启变化,每次换环境需要重新查看 IP。
五、接口调试方法
console.log打印数据,在 RN 启动终端查看日志- 终端按
j打开 Expo JS 调试器,在 Console 面板查看返回数据
注意:Expo SDK 54+ Windows、SDK56 全平台,调试器 Network 面板无法查看网络请求,属于 Expo 已知问题,不影响开发,使用 Console 打印调试即可。
七、总结
- JSX 列表渲染:数组
.map(),必须携带唯一 key; - 后端服务:Node + Prisma SQLite,启动三步:
npm i→npx prisma generate→npm start; - RN 网络请求:原生 Fetch API,搭配 async/await,
.json()解析响应; - 网络大坑:模拟器 / 真机不能用 localhost,改用电脑局域网 IP,手机电脑同一局域网;
完整链路:后端接口服务启动 → RN 点击按钮 fetch 请求 → state 更新 → map 渲染列表。这就是移动端前后端联调最基础的完整闭环。
从假数据到真实接口一气呵成,SQLite + Prisma 方案降低了后端门槛,模拟器与真机 IP 踩坑部分尤其实用。适合 RN 初学者完成首次前后端联调。