数据获取与错误边界
fetch API、loading/error、Error Boundary 概念。
数据获取与错误边界
这一课你将能做到
- 用状态机思想处理 loading / success / error
- 在 Effect 里请求时防止「过期响应」写回界面
- 知道错误边界大概接住什么、接不住什么
为什么要学
真实页面要向后端要数据:课程标题、进度、题库。
网络慢、失败、返回空,都要有界面,而不是白屏或转圈到永远。
人话:请求不是「发出去就一定成功」;界面要诚实说出三种情况——还在等、等到了、失败了。
本站 lib/api 封装了 fetch;本课用手写状态机,把模式看清。Next 服务端取数能少写样板,思想相同。
先建立图像
idle → loading → success
↘ error →(可重试,回到 loading)
另外:用户已经切到另一门课,上一门的响应才到——必须丢掉(dead 旗标)。
跟着做
步骤 1:手写状态(完整可抄)
import { useEffect, useState } from "react";
export function TrackTitle({ slug }) {
const [state, setState] = useState({ status: "loading" });
useEffect(() => {
let dead = false;
setState({ status: "loading" });
fetch("/api/tracks/" + slug)
.then((r) => {
if (!r.ok) throw new Error("HTTP " + r.status);
return r.json();
})
.then((data) => {
if (!dead) setState({ status: "ok", data });
})
.catch((err) => {
if (!dead) {
setState({
status: "error",
message: String(err.message || err),
});
}
});
return () => {
dead = true;
};
}, [slug]);
if (state.status === "loading") return <p>加载中…</p>;
if (state.status === "error") {
return <p>失败:{state.message}</p>;
}
return <h1>{state.data.title}</h1>;
}
空数据:ok 之后列表 length 为 0,显示「暂无」,不要假装还在加载。
步骤 2:401 与业务失败
HTTP 401:引导登录,而不是只写「失败」。
400 校验错误:把后端返回的消息展示在表单附近。
这些都是「错误 UI」,不是只打日志。
步骤 3:错误边界(概念,别当万能网)
类组件或库提供的 Error Boundary:子组件渲染期间抛错时,显示降级 UI(「这块坏了」),避免整页白屏。
它接不住:
- 事件处理里的
throw - 异步
fetch里的多数错误 - 服务端很多错误(看框架)
网络错误仍要自己 catch 并 setState。边界是渲染期的安全带,不是 try/catch 替代品。
步骤 4:重试
错误 UI 上放按钮:再次 setState({ status: "loading" }) 或把 retryCount 放进 Effect 依赖。
连点重试同样要考虑 in-flight。