1. 课程导入与工程环境搭建

React Native 应用一旦离开纯本地演示阶段,就必然要面对网络请求、接口鉴权、数据缓存、离线容错、上传下载、实时通信等问题。本课程围绕“网络与数据工程”展开,目标不是记住某个 API 的调用形式,而是建立一套可复用的工程方法:知道数据从哪里来、经过哪些层、在什么条件下失败、失败后如何恢复,以及如何用可观测的手段验证结果。本章作为学习地图与起点,先厘清核心概念,再完成环境搭建,最后跑通第一个真实网络请求。

一、学习地图:从请求到数据闭环

React Native 的网络与数据工程可以拆成五个相互衔接的层次。第一层是传输层,由 fetch、XMLHttpRequest 以及底层原生网络栈承担,负责把 HTTP/HTTPS 请求发出去并接收响应。第二层是协议与接口层,关注 REST、GraphQL、WebSocket 等接口形态,以及状态码、请求头、超时、重试等约定。第三层是数据管理层,处理响应解析、类型校验、缓存、分页、乐观更新与本地持久化。第四层是状态与视图层,把远程数据映射为组件可消费的状态,处理加载中、空数据、错误、成功四种典型界面。第五层是可观测与工程化层,包括日志、错误上报、性能指标、Mock 与测试。

这五层不是必须逐层实现的瀑布,而是排查问题时的定位坐标。例如请求一直 pending,优先怀疑传输层与超时配置;数据偶发为 undefined,优先怀疑协议层字段约定或数据管理层校验缺失;界面闪烁,则多半是状态层没有区分“首次加载”和“刷新”。

React Native 网络与数据工程 · 五层学习地图 ① 传输层 fetch / XMLHttpRequest / 原生网络栈 · 超时 · 取消 · 重试 ② 协议与接口层 REST / GraphQL / WebSocket · 状态码 · 请求头 · 鉴权 ③ 数据管理层 解析 · 类型校验 · 缓存 · 分页 · 乐观更新 · 本地持久化 ④ 状态与视图层 加载中 / 空数据 / 错误 / 成功 · 刷新与分页状态 ⑤ 可观测与工程化层 日志 · 错误上报 · 性能指标 · Mock · 测试

二、核心概念:先统一几个容易混淆的词

请求与响应:一次网络交互由请求方法、URL、请求头、请求体组成,服务端返回状态码、响应头与响应体。React Native 中 fetch 返回的 Promise 只有在网络层失败时才 reject;HTTP 404、500 这类“服务器有响应但状态码非 2xx”的情况,Promise 仍然 resolve,必须手动检查 response.ok 或 response.status。这是初学者最常见的坑。

序列化与反序列化:请求体通常需要 JSON.stringify,响应体需要 response.json()。注意 response.json() 本身也返回 Promise,且只能读取一次响应体。

超时与取消:fetch 默认没有超时,需要借助 AbortController 主动中断。组件卸载后仍 setState 会触发警告,因此取消请求是工程必备。

环境变量与接口地址:开发、测试、生产环境的 baseURL 不同。React Native 没有浏览器那样的 process.env 注入,常用做法是用 react-native-config 或自建 env.ts 按 __DEV__ 分支导出配置。

三、开发环境搭建

推荐使用 Expo 起步,它屏蔽了大部分原生配置,适合把精力放在网络与数据逻辑上。若后续需要接入自定义原生模块,再执行 npx expo prebuild 转为原生工程。

# 1. 创建项目
npx create-expo-app rn-net-lab --template blank-typescript
cd rn-net-lab

# 2. 安装网络与调试相关依赖
npx expo install @react-native-async-storage/async-storage
npm i axios zustand

# 3. 启动开发服务器
npx expo start

启动后可用 Expo Go 扫码在真机运行,或按 a / i 启动模拟器。真机调试时注意:手机与电脑需在同一局域网;若接口部署在本机,Android 模拟器访问宿主机要用 10.0.2.2,iOS 模拟器可直接用 localhost,真机则需使用电脑的局域网 IP。

建议在项目根目录建立 src/config/env.ts,集中管理 baseURL 与超时时间,避免接口地址散落在各个组件中。

四、第一个网络请求示例

下面用一个公开测试接口 https://jsonplaceholder.typicode.com/posts/1 演示完整流程:发起请求、检查状态码、解析 JSON、渲染结果,并处理加载与错误状态。示例中的返回数据为公开测试接口的典型结构,仅用于教学演示。

import React, { useEffect, useState } from 'react';
import { View, Text, ActivityIndicator, Button } from 'react-native';

type Post = { userId: number; id: number; title: string; body: string };

export default function FirstRequest() {
  const [data, setData] = useState<Post | null>(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const load = async () => {
    setLoading(true);
    setError(null);
    const controller = new AbortController();
    const timer = setTimeout(() => controller.abort(), 8000);
    try {
      const res = await fetch(
        'https://jsonplaceholder.typicode.com/posts/1',
        { signal: controller.signal }
      );
      if (!res.ok) throw new Error(`HTTP ${res.status}`);
      const json: Post = await res.json();
      setData(json);
    } catch (e: any) {
      setError(e.name === 'AbortError' ? '请求超时' : e.message);
    } finally {
      clearTimeout(timer);
      setLoading(false);
    }
  };

  useEffect(() => { load(); }, []);

  if (loading) return <ActivityIndicator size="large" />;
  if (error) return <View><Text>出错:{error}</Text><Button title="重试" onPress={load} /></View>;
  return (
    <View>
      <Text>{data?.title}</Text>
      <Text>{data?.body}</Text>
    </View>
  );
}

运行后应看到标题与正文文本。若长时间转圈,检查网络与接口地址;若显示“出错:HTTP 404”,说明路径写错;若显示“请求超时”,说明 8 秒内未收到响应。这个最小闭环已经包含了后续所有章节都会反复用到的骨架:状态三件套(data / loading / error)+ 超时控制 + 状态码检查 + 重试入口。

五、本章实践检查清单

检查项预期结果不通过时的排查方向
项目可启动Expo 开发服务器正常,真机或模拟器可加载Node 版本、依赖安装、局域网连通性
接口可访问返回 200 且 JSON 含 id/title/bodyURL 拼写、baseURL、模拟器宿主地址
加载态可见请求期间显示 ActivityIndicatorloading 状态是否在 finally 中复位
错误态可重试断网或改错 URL 后显示错误并可点击重试是否检查 res.ok、是否捕获 AbortError
超时生效8 秒无响应时提示“请求超时”AbortController 是否绑定到 signal