CodeRoadMap
首页路线题库资源库文章社区
CodeRoadMap

程序员的学习成长路线图。内容免费开放,登录后可同步路线图与课时进度。

由 程序员柏风 独立维护 · 关于作者

学习

  • 路线图
  • 课程
  • 面试题
  • 文章
  • 我

更多

  • 资源
  • 社区
  • 关于作者
  • 内容说明

© 2026 CodeRoadMap

津ICP备2026012044号-1·津公网安备12011002026155号·coderoadmap@126.com
React 核心/课时/数据获取与错误边界
RawBlame
课时目录14 节

React 核心

  1. 01React 是什么
  2. 02JSX 与渲染
  3. 03函数组件
  4. 04Props 与 State
  5. 05事件处理
  6. 06条件渲染与列表
  7. 07useEffect
  8. 08useRef 与 DOM
  9. 09useMemo、useCallback 与自定义 Hook
  10. 10表单与受控组件
  11. 11Context 共享状态
  12. 12React Router 入门
  13. 13数据获取与错误边界
  14. 14综合练习与 Next.js 方向

数据获取与错误边界

fetch API、loading/error、Error Boundary 概念。

35 分钟

数据获取与错误边界

这一课你将能做到

  1. 用状态机思想处理 loading / success / error
  2. 在 Effect 里请求时防止「过期响应」写回界面
  3. 知道错误边界大概接住什么、接不住什么

为什么要学

真实页面要向后端要数据:课程标题、进度、题库。
网络慢、失败、返回空,都要有界面,而不是白屏或转圈到永远。

人话:请求不是「发出去就一定成功」;界面要诚实说出三种情况——还在等、等到了、失败了。

本站 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。

步骤 5:错误与空态

if (error) return <p role="alert">{error}</p>;
if (!rows.length) return <p>暂无课程</p>;

把 error / empty / list 分开,避免「失败还显示旧列表」却不提示。

讲清楚要点

  1. 永远给用户反馈:加载中、失败原因、空数据。
  2. slug 变化要重拉,并取消过期写回。
  3. Next 服务端取数可少写这类样板,但思想相同。
  4. 错误边界 ≠ 捕获 fetch。
  5. 成功态也不要闪旧数据:切 slug 时先回到 loading,或明确标「刷新中」。

你可能会懵的地方

  • 为何有时闪一下旧标题?
    没在依赖变化时把状态打回 loading,旧 ok 还在。

  • Strict Mode 开发打两次请求?
    与 Effect 课相同;cleanup 把 dead 设上即可。

  • SWR / React Query?
    缓存、重试、去重它们能做。入门先会手写状态机,再用库。

  • 把 JSON 直接当 JSX 孩子?
    对象不能当孩子。渲染字段。

  • Error Boundary 吃掉事件错误?
    主要吃渲染期错误;事件处理器里要自己 try/catch 或设 error state。

错法对照

错法问题正解
无 loading像卡死明确加载态
无 dead 旗标错乱 setStatecleanup
只 console 不展示用户懵错误 UI
靠错误边界接住 fetch接不住catch + 状态
失败仍显示上一门课当成功误导切走就 loading/清空
只 setData 不处理 !ok静默坏数据检查 res.ok
加载中仍可重复狂点重复请求disabled / abort

自测三问

  1. 三种状态各应给用户看什么?空列表算哪一种?
  2. dead 旗标在防什么?
  3. 错误边界能不能接住点击事件里的 throw?能不能接住 fetch 失败?

小结一句话

取数要有状态机与过期保护;错误要可见,边界只是渲染期兜底。

练习:故意把 fetch 的路径写错,确认页面出现失败文案而不是一直「加载中」。再快速切换两个 slug,确认不会把先发出、后返回的那一门标题盖到新课上。

动手加深

Client fetch 课表:loading → ok/error;切换课程时 abort 上一次。再读 Next 轨服务端取数对比。

跟着做(加厚 · react-data)

步骤:最小可运行对照

在 Vite 或 Next 练习页粘贴本课核心示例,改一个输入,确认屏幕变化符合预期。再故意写一个错法表里的写法,看控制台/界面如何坏,然后改回。

每个概念都问:state 在谁手里?UI 哪一块会因它重绘?

操作顺序:打开对应文件 → 改一处可观察点(文案、类型、className 或分支)→ 保存看结果 → 复原或留下有意义的小改动。

步骤:错法故意练一次

先按「用 jQuery 式直接改 DOM 冒充完成」做 30 秒(或在注释里写出若这样做会怎样),再改成「改数据(state/props)让 UI 推导出来」。 目的不是留坑,而是让失败现象进长期记忆。

你可能会懵的地方(加厚)

  • 热更新后状态丢了?
    正常:整树重挂会重置 state。用 key 或外提状态保留;开发期别被吓到。

  • 和文档示例不一致?
    以你锁的 React 大版本 + react.dev 为准;旧博客的 class 组件示例仅作历史阅读。

  • 这课和前后课怎么接?
    回看大纲上一课的小结一句、下一课标题;用自己的话写「本课产出什么可观察结果」。写不出来就重做跟着做。

错法对照(加厚)

错法问题正解
用 jQuery 式直接改 DOM 冒充完成假完成/埋雷改数据(state/props)让 UI 推导出来
只看不敲第二天全忘至少跑通本课步骤
跳过自测三问以为会了闭卷答再对稿

延伸

  • react.dev 错误处理相关;对照本站 lib/api
  • 下一课:综合练习,并通向 Next.js。
加载本节练习…
← 上一课React Router 入门下一课 →综合练习与 Next.js 方向