做产品 PMaker
只写了正常态
四态齐全
切换后端返回的情况:

同一个列表组件,左边是让 AI 直接写出来的版本,右边补齐了四种状态。点上面的按钮切换。

四态齐全

一块界面在真实环境里会出现四种样子,AI 通常只做出其中一种。剩下三种要么一片空白,要么直接把报错摊在用户面前。

你会遇到的现象
  • 自己演示一切正常,同事一登录就是白屏,因为他账号里没数据
  • 网慢的时候页面先塌下去,数据回来又撑开,正要点的按钮跑掉了
  • 接口一挂整页变成 Uncaught TypeError,用户只能刷新碰运气

原因不在模型。你说做一个订单列表,它脑子里的画面就是一屏排列整齐的订单,因为你给它的描述里也只有这一种。空、加载、出错这三种情况在需求文档里从来不出现,只在真实用户手上出现:新注册的人第一次打开、地铁里信号断了、后端刚好在发版。

补齐的成本通常是几十行代码。真正的门槛是在写需求的时候就把它们当成需求的一部分,而不是等 bug 报上来再补。

怎么判断

任何一次取数据,结果只会落在四个格子里。照着这张图问一遍,就知道少写了哪个。

发起请求 还没回来 失败了 成功,但没数据 成功,有数据 加载态 错误态 空态 正常态 还要多久,页面会不会跳 怎么回事,我能做什么 为什么是空的, 下一步该干什么 最重要的那条看得到吗
空态还要再分一层:是这个人本来就没有数据,还是筛选条件把数据筛没了。前者引导他创建,后者提示放宽条件并给一键清除。

设计考量

提示用什么形式,取决于这件事严不严重。三档从强到弱,越级使用的代价是用户很快学会闭眼点确定。

弹窗 · 强 必须立刻处理的错误 全局横幅 · 中 状态变化,不必立刻行动 气泡 · 弱 可看可不看的信息
强度分档参考了提示语设计的常见做法。判断标准很简单:这件事如果用户不处理,会不会出问题。

给 AI 的话

放进组件需求,或者直接沉淀到项目的 CLAUDE.md,之后每次生成数据组件都会默认带上四态。

PROMPT · 组件需求
凡是涉及异步数据的组件,必须同时实现四种状态,缺一不可:

1. 正常态:有数据时的正常渲染。
2. 空态:数据为空数组时。区分两种来源——
   - 用户还没有任何数据:给一句说明 + 一个主行动按钮
   - 筛选/搜索后无结果:提示放宽条件 + 一键清除筛选
3. 加载态:使用骨架屏,形状和数量贴近真实内容,不要用居中 spinner。
4. 错误态:按「说明当前状况 + 引导措施」写文案,配一个「重试」按钮,
   不要暴露状态码或堆栈。

文案规范:
- 不使用感叹号;句尾除疑问句外不加标点。
- 等待类文案统一以「…」结尾,例如「加载中…」。
- 提示强度分三档:必须立刻处理用弹窗,状态变化用全局横幅,
  可看可不看用气泡。不要越级。

其他约束:
- 四种状态复用同一个外层容器,设置 min-height 避免切换时页面跳动。
- 错误只影响当前组件,不要向上冒泡导致整页变成错误页。
- 把状态做成组件的一个 prop('ok' | 'empty' | 'loading' | 'error'),
  这样我可以在不改后端的情况下逐个预览。

先告诉我这四种状态分别打算怎么呈现,我确认后你再写代码。

最后一句很关键。让它先描述方案,你能在几秒内看出空态是不是又写成了四个字的暂无数据,比读完代码再返工快得多。

真实案例

还没有任何笔记

你写的东西会出现在这里,随时可以搜索和整理。

新建第一篇

Notion 的空数据库会给出几个模板选项和一个创建入口,用这块地方教用户接下来做什么。

Linear 的加载骨架复刻了真实内容的行高和分栏,数据到达时几乎察觉不到切换,页面不发生跳动。