React Native 2:列表渲染 + 后端接口搭建 + Fetch 请求数据

文章来源声明: 原文作者:是你的小橘呀; 来源站点:掘金; 原文链接:https://juejin.cn/post/7691142360247779363; 本文基于上述来源整理/加工,觅优补充点评,仅供技术学习交流。版权归原作者所有。
觅优短评

从假数据到真实接口一气呵成,SQLite + Prisma 方案降低了后端门槛,模拟器与真机 IP 踩坑部分尤其实用。适合 RN 初学者完成首次前后端联调。

前言 --

在 React Native App 开发中,列表渲染和网络请求是两个最基础、高频的能力。 本篇文章一次性带你走完完整流程:

  1. 使用 map 遍历数组渲染列表,理解 key 的作用
  2. 启动本地 Node 后端 API(SQLite + Prisma,配套示例 JSON 返回样例,无需依赖外部在线接口服务)
  3. RN 使用原生 fetch 请求后端接口,展示真实数据
  4. 踩坑: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 核心要点

  1. {} 在 JSX 中用来嵌入 JS 表达式

  2. .map() 遍历数组,返回新的 JSX 元素数组,完成渲染

  3. 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运行环境,导入数据库了。

数据库的管理,有两种方法:

  1. **Prisma Studio(网页版)**新开终端,进入 zxj‑api:
<span># 默认端口</span>
npx prisma studio
<span># 如果端口5555冲突(Android模拟器占用),更换端口</span>
npx prisma studio -p 5556

浏览器自动打开可视化数据库面板,可以直接增删改查。

  1. 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>

  • 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>,
  },
});

image.png

  • 函数的名字,叫做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。

五、接口调试方法

  1. console.log 打印数据,在 RN 启动终端查看日志
  2. 终端按 j 打开 Expo JS 调试器,在 Console 面板查看返回数据

注意:Expo SDK 54+ Windows、SDK56 全平台,调试器 Network 面板无法查看网络请求,属于 Expo 已知问题,不影响开发,使用 Console 打印调试即可。

七、总结

  1. JSX 列表渲染:数组 .map(),必须携带唯一 key;
  2. 后端服务:Node + Prisma SQLite,启动三步:npm i → npx prisma generate → npm start;
  3. RN 网络请求:原生 Fetch API,搭配 async/await,.json() 解析响应;
  4. 网络大坑:模拟器 / 真机不能用 localhost,改用电脑局域网 IP,手机电脑同一局域网;

完整链路:后端接口服务启动 → RN 点击按钮 fetch 请求 → state 更新 → map 渲染列表。这就是移动端前后端联调最基础的完整闭环。