Three-State Fetching 请求三态处理

最后更新:2026-10-28

Three-State Fetching 请求三态处理

任何数据请求都有三种状态:loading(请求中)、success(拿到数据)、error(失败)。UI 必须为三态各准备一帧,缺任何一态都会出现白屏、死等或无声失败。这是手写 fetch 与使用请求库共通的心智模型。

分组数据与工程化
类型模式

ℹ️ 说明 编辑器将 JSX 转译为 JavaScript 后在沙箱中渲染真实界面;组件自动挂载,无需手写 render 调用。

📝 语法

const [state, setState] = useState({ status: 'loading', data: null, error: null })

useEffect(() => {
  fetch(url)
    .then(r => r.ok ? r.json() : Promise.reject(new Error('HTTP ' + r.status)))
    .then(data => setState({ status: 'success', data, error: null }))
    .catch(err => setState({ status: 'error', data: null, error: err }))
}, [url])

if (state.status === 'loading') return <p>加载中…</p>
if (state.status === 'error')   return <p>出错:{state.error.message}</p>
return <List data={state.data} />

⚙️ 参数

status状态机的当前态:'loading' | 'success' | 'error';也可用 isLoading/isError 两个字段表达。

返回值:无返回值,作为编码模式使用

▶ 示例

示例可直接运行:展开后自动渲染,编辑代码即时生效。

输出结果:

首次自动请求显示「加载中」;成功后展示 todo 标题;断网或接口故障时显示错误信息与重试按钮——三态各占一帧。

💡 要点

⚠️ 注意 fetch 对 404/500 不会 reject(只有网络层错误才 reject),务必检查 r.ok 再抛错,否则业务错误会静默进入 success 分支。
💡 提示 把 status 收进一个 state 对象而不是三个布尔值,杜绝「loading 为 true 且 error 也有值」的非法组合。
ℹ️ 说明 TanStack Query 把这套状态机内置化(isPending/isError/data),手写三态是理解它的最好前置。
更多案例整理中,敬请期待。

📚 相关教程

❓ 常见问题

Q 用三个布尔 isLoading/isError/hasData 代替 status 行吗?
A 可以但容易产生非法组合(比如同时为 true)。单一 status 字段是状态机思想,组合天然合法。
Q 请求失败要自动重试吗?
A 视业务:读操作可指数退避重试 2-3 次;写操作必须人工确认,避免重复下单。
Q loading 期间要禁止操作吗?
A 提交类请求要禁用按钮防重复提交;读请求不必整体锁界面,可用骨架屏保持可交互感。
Web-Tutorial.com

Web-Tutorial 技术团队

由多位开发者共同维护的编程教程平台。每篇教程由对应领域的开发者编写和审核,确保内容准确可靠。如发现任何问题,欢迎向我们反馈。

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏