Ant Design Result 组件完全指南:状态页设计与源码级实现解析
【免费下载链接】ant-designAn enterprise-class UI design language and React UI library项目地址: https://gitcode.com/gh_mirrors/ant/ant-design
导读
Ant Design Result 是面向「操作结果反馈」场景的企业级状态页组件:当一次重要操作执行完毕后,需要向用户清晰传达成功、失败或异常等结果信息,且反馈内容较为复杂(包含标题、副标题、操作按钮、错误详情等)时,Result 提供了开箱即用的解决方案。本文将围绕官方文档的 When To Use、Examples、API 与 Design Token 四个核心板块,结合仓库中 index.tsx 的渲染逻辑、style/index.ts 的样式令牌实现以及全部 9 个官方示例,讲解七种状态(success/info/warning/error/403/404/500)的选型与用法、自定义图标、内置异常插画复用,以及如何通过ConfigProvider精确调整组件样式令牌,帮助你在实际项目中快速落地规范统一的结果页与错误页。
何时使用 Result
官方文档给出的使用场景非常明确:
Use when important operations need to inform the user to process the results and the feedback is more complicated.
翻译过来即:当一次重要操作需要告知用户处理结果,且反馈内容比较复杂时使用。典型场景包括:
- 支付、下单、提交表单成功后的结果页(成功态);
- 登录失效、权限不足的拦截页(403);
- 路由不存在、链接失效的兜底页(404);
- 服务端异常、系统错误的容错页(500);
- 需要展示错误明细列表、并提供「重新提交」「返回控制台」等操作入口的错误反馈。
如果只是简单的轻量反馈(如操作提示、全局通知),则应优先考虑 Message 或 Notification 组件,而不是 Result。
核心概念:七种状态与默认呈现
Result 的全部表现力都建立在status属性之上。在 index.tsx 中,状态被拆分为两个映射表:
IconMap —— 图标型状态(对应语义图标):
| 状态 | 图标 | 语义 |
|---|---|---|
success | CheckCircleFilled | 操作成功 |
error | CloseCircleFilled | 操作失败 |
info | ExclamationCircleFilled | 信息提示 |
warning | WarningFilled | 警告提醒 |
ExceptionMap —— 异常插画型状态(对应内置 SVG 插画):
| 状态 | 插画组件 | 源码文件 |
|---|---|---|
403 | unauthorized | unauthorized.tsx |
404 | noFound | noFound.tsx |
500 | serverError | serverError.tsx |
在组件内部,Icon子组件通过ExceptionStatus.includes(\${status}`)判断当前状态属于哪一类:若为异常插画型,则渲染ExceptionMap中对应的 SVG 插画(外层包裹.result-image容器);否则从IconMap中取出语义图标渲染(外层包裹.result-icon容器)。插画容器在 [style/index.ts](https://link.gitcode.com/i/f1c33b76a9882fffb8648713fa37c512) 中固定为imageWidth: 250、imageHeight: 295,配合margin: 'auto'` 居中显示。
需要特别注意的是:status的默认值是info(源码status = 'info'),因此即使完全不传status,组件也会渲染一个信息图标。同时异常状态支持字符串与数字两种写法,类型定义ExceptionStatusType = 403 | 404 | 500 | '403' | '404' | '500',测试用例 type.test.tsx 中同时覆盖了<Result status="404">与<Result status={404}>两种写法。
API 属性详解
官方文档的 API 表格如下,结合 ResultProps 接口可以还原出完整属性集:
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| extra | 操作区,一般放置按钮 | ReactNode | - |
| icon | 自定义图标(自定义返回图标) | ReactNode | - |
| status | 结果状态,决定图标与颜色 | success|error|info|warning|404|403|500 | info |
| subTitle | subTitle 副标题 | ReactNode | - |
| title | title 标题 | ReactNode | - |
| children | 结果内容区,用于展示错误明细等复杂信息 | ReactNode | - |
| className / rootClassName | 自定义类名 | string | - |
| style | 自定义样式 | CSSProperties | - |
| prefixCls | 样式类名前缀 | string | - |
官方文档中「Common props」参考了 docs/react/common-props(即className、style、prefixCls等通用属性说明)。以下几个关键行为值得展开:
- icon 优先级:自定义
icon优先于状态默认图标渲染;但传入icon={null}或icon={false}时会直接不渲染图标区域(源码中if (icon === null || icon === false) return null;); - icon 类型校验:开发环境下若
icon传入长度大于 2 的字符串,会通过devUseWarning('Result')发出 breaking 级警告,提示 v4 起icon应使用 ReactNode 而非字符串名称(参见 index.tsx); - children 内容区:children 会渲染到
.result-content容器中,样式带有colorFillAlter背景色与内边距,适合放置错误明细、步骤说明等结构化内容。
实战示例:七种状态页的完整写法
以下代码均取自官方 Demo 目录(components/result/demo),可直接复制使用。
成功页(Success)
import React from 'react'; import { Button, Result } from 'antd'; const App: React.FC = () => ( <Result status="success" title="Successfully Purchased Cloud Server ECS!" subTitle="Order number: 2017182818828182881 Cloud server configuration takes 1-5 minutes, please wait." extra={[ <Button type="primary" key="console">Go Console</Button>, <Button key="buy">Buy Again</Button>, ]} /> ); export default App;要点:extra接收 ReactNode 数组时,多个操作按钮会横向排列(.result-extra中相邻元素自动加marginInlineEnd间距);主操作使用type="primary"突出,次操作使用默认样式。
信息页(Info)与警告页(Warning)
信息页不传status即为默认的info状态:
import React from 'react'; import { Button, Result } from 'antd'; const App: React.FC = () => ( <Result title="Your operation has been executed" extra={<Button type="primary" key="console">Go Console</Button>} /> ); export default App;警告页仅需将状态切换为warning:
<Result status="warning" title="There are some problems with your operation." extra={<Button type="primary" key="console">Go Console</Button>} />错误页(Error)+ 错误明细
错误态与children内容区配合,可展示详细的错误条目列表:
import React from 'react'; import { CloseCircleOutlined } from '@ant-design/icons'; import { Button, Result, Typography } from 'antd'; const { Paragraph, Text } = Typography; const App: React.FC = () => ( <Result status="error" title="Submission Failed" subTitle="Please check and modify the following information before resubmitting." extra={[ <Button type="primary" key="console">Go Console</Button>, <Button key="buy">Buy Again</Button>, ]} > <div className="desc"> <Paragraph> <Text strong style={{ fontSize: 16 }}> The content you submitted has the following error: </Text> </Paragraph> <Paragraph> <CloseCircleOutlined /> Your account has been frozen. <a>Thaw immediately ></a> </Paragraph> <Paragraph> <CloseCircleOutlined /> Your account is not yet eligible to apply. <a>Apply Unlock ></a> </Paragraph> </div> </Result> ); export default App;HTTP 异常页:403 / 404 / 500
三个异常状态共享同一套写法,区别仅在status与文案:
// 403:无权限 <Result status="403" title="403" subTitle="Sorry, you are not authorized to access this page." extra={<Button type="primary">Back Home</Button>} /> // 404:页面不存在 <Result status="404" title="404" subTitle="Sorry, the page you visited does not exist." extra={<Button type="primary">Back Home</Button>} /> // 500:服务器错误 <Result status="500" title="500" subTitle="Sorry, something went wrong." extra={<Button type="primary">Back Home</Button>} />这三个状态渲染的是仓库内置的精美 SVG 插画(非字体图标),可直接作为路由 404 页面、权限校验失败页和全局异常兜底页使用。
自定义图标:icon 属性的应用
如果内置的状态图标或异常插画不满足品牌需求,可以通过icon传入任意 ReactNode 完全替换默认图标:
import React from 'react'; import { SmileOutlined } from '@ant-design/icons'; import { Button, Result } from 'antd'; const App: React.FC = () => ( <Result icon={<SmileOutlined />} title="Great, we have done all the operations!" extra={<Button type="primary">Next</Button>} /> ); export default App;注意该示例未传status,此时状态默认是info,但渲染层以icon为准。从 Icon 子组件 的实现可以确认渲染优先级为:异常状态 SVG 插画 > 自定义 icon > 状态默认图标(icon为null/false时图标区域整体不渲染)。
复用内置插画:PRESENTED_IMAGE 静态属性
Result 组件将三张异常插画以静态属性的方式直接暴露,便于你在脱离 Result 组件外壳的场景(如自定义弹窗、Empty 状态、Loading 占位)中单独复用:
import { Result } from 'antd'; // 在任意位置直接渲染 404 插画 const App = () => ( <div style={{ width: 252, margin: 'auto' }}> <Result.PRESENTED_IMAGE_404 /> </div> );源码中的挂载逻辑如下(index.tsx):
Result.PRESENTED_IMAGE_403 = ExceptionMap['403']; Result.PRESENTED_IMAGE_404 = ExceptionMap['404']; Result.PRESENTED_IMAGE_500 = ExceptionMap['500'];插画均为独立的 SVG React 组件,分别位于 unauthorized.tsx、noFound.tsx 与 serverError.tsx,视觉尺寸约 252×294。
样式定制:Design Token 与主题配置
官方文档末尾提供了<ComponentTokenTable component="Result" />,对应组件级 Design Token 定义在 style/index.ts 中,共四个可配置项:
| Token | 说明 | 默认值来源 |
|---|---|---|
| titleFontSize | 标题字体大小 | token.fontSizeHeading3(即 24px 级) |
| subtitleFontSize | 副标题字体大小 | token.fontSize(基础 14px) |
| iconFontSize | 图标大小 | token.fontSizeHeading3 * 3(72px) |
| extraMargin | 额外区域外间距 | ${token.paddingLG}px 0 0 0(24px 上边距) |
此外还有一组仅在组件内部使用的派生 token:resultInfoIconColor(colorInfo)、resultSuccessIconColor(colorSuccess)、resultWarningIconColor(colorWarning)、resultErrorIconColor(colorError),它们决定了各状态下图标颜色,并通过genStatusIconStyle分别写入.result-success-icon、.result-error-icon等选择器(style/index.ts)。
通过ConfigProvider即可在应用级或局部覆盖这些 token(官方 Demo component-token.tsx):
import React from 'react'; import { Button, ConfigProvider, Result } from 'antd'; const App: React.FC = () => ( <ConfigProvider theme={{ components: { Result: { titleFontSize: 18, subtitleFontSize: 14, iconFontSize: 48, extraMargin: `12px 0 0 0`, }, }, }} > <Result status="success" title="Successfully Purchased Cloud Server ECS!" subTitle="Order number: 2017182818828182881 Cloud server configuration takes 1-5 minutes, please wait." extra={[ <Button type="primary" key="console">Go Console</Button>, <Button key="buy">Buy Again</Button>, ]} /> </ConfigProvider> ); export default App;如果希望进一步调整异常插画区域的尺寸,从源码看该尺寸由内部 tokenimageWidth(250)与imageHeight(295)控制,暂未开放为组件级 token,需通过自定义 CSS 覆盖.result-image实现。整个样式体系经由genStyleHooks生成,支持 cssinjs 的 hashId 隔离与 CSS 变量模式,与主题系统无缝衔接。
源码级行为补充:前缀类名与 RTL
- prefixCls 注入:组件通过
ConfigContext的getPrefixCls('result', customizePrefixCls)生成类名前缀,因此可用ConfigProvider prefixCls全局或局部调整前缀,用于多主题/多品牌场景; - RTL 支持:当
ConfigProvider direction="rtl"时,组件根节点会追加result-rtl类并设置direction: rtl,同时.result-extra内部使用marginInlineEnd而非marginRight做间距,天然适配 RTL 布局(style/index.ts); - 渲染顺序:根节点内依次渲染 图标(Icon)→ 标题(title)→ 副标题(subTitle)→ 操作区(extra)→ 内容区(children),其中 subTitle、extra、children 为空时对应 DOM 均不输出,避免多余节点。
上述渲染顺序、默认状态、警告行为等均已由测试用例覆盖,见 components/result/tests/index.test.tsx(覆盖success/warning/error/500/404各状态渲染与类名合并)与 type.test.tsx(覆盖状态类型与异常状态数字写法)。
小结
Result 组件以status为唯一核心驱动,向下分流为语义图标(success/error/info/warning)与内置 SVG 插画(403/404/500)两条渲染路径,配合title/subTitle/extra/children四块内容区域即可拼装出完整的状态页。在工程实践中,建议将 404/403/500 页面直接以 Result 为基础封装为全局路由兜底组件,将成功/失败反馈封装为可复用的结果页模板,并通过ConfigProvider统一收敛样式 token,从而在整站范围内保持结果反馈的视觉与交互一致性。
【免费下载链接】ant-designAn enterprise-class UI design language and React UI library项目地址: https://gitcode.com/gh_mirrors/ant/ant-design
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考