ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

ant-design 中使用 ConfigProvider 的 renderEmpty 自定义全局组件 Empty 空状态

2026/9/8 22:39:36 拓冰建站 浏览量
ant-design 中使用 ConfigProvider 的 renderEmpty 自定义全局组件 Empty 空状态 ant-design 中使用 ConfigProvider 的 renderEmpty 自定义全局组件 Empty 空状态【免费下载链接】ant-designAn enterprise-class UI design language and React UI library项目地址: https://gitcode.com/GitHub_Trending/an/ant-design导读本文围绕 ant-design 官方示例「Use ConfigProvider set global Empty style」展开讲解如何通过ConfigProvider的renderEmpty配置项一次性替换 Select、Table、List、Transfer、Cascader、TreeSelect、Mentions 等内置组件的全局空状态Empty样式。读完你将掌握renderEmpty的完整 API、其默认行为背后的源码实现以及局部/全局切换、多 Provider 嵌套等实战用法。一、这个示例在解决什么问题ant-design 中很多组件在“没有数据”时都会渲染一个默认的空状态占位Empty组件Select 无下拉选项、Table 无数据、Transfer 无待选项、Cascader / TreeSelect / List / Mentions 为空时都会展示。默认占位是内置的插画风格图片但在业务中往往需要换成符合自己产品语义的文案与图形。components/empty/demo/config-provider.md 对应的示例 components/empty/demo/config-provider.tsx 演示的正是官方推荐的全局定制方案借助ConfigProvider.renderEmpty把整棵组件树下所有内置组件默认使用的 Empty 一键替换成自定义内容并在一个 Switch 上实时切换customize/default两种状态。这里要区分两个层面单点定制给某个Empty传image、description或children只影响当前组件实例全局定制通过ConfigProvider renderEmpty{...}定制影响其下所有用到“内置空状态”的组件这正是本示例的核心主题。二、renderEmpty 能接管哪些组件的空状态renderEmpty的类型签名定义在 components/config-provider/index.tsxrenderEmpty?: RenderEmptyHandler;而RenderEmptyHandler定义于 components/config-provider/defaultRenderEmpty.tsxexport type RenderEmptyHandler (componentName?: ComponentName) React.ReactNode; type ComponentName | Table | Table.filter /* 5.20.0 */ | List | Select | TreeSelect | Cascader | Transfer | Mentions;也就是说renderEmpty是一个接收componentName字符串并返回ReactNode的函数。你既可以用它一次性覆盖所有组件的空状态也可以根据传入的组件名做差异化渲染。官方 API 文档中的描述见 components/config-provider/index.en-US.md「Set empty content of components」——即“设置组件的空内容”。哪些组件在何时回调它可以看实际调用点例如 components/select/index.tsx 中mergedNotFound renderEmpty?.(Select) || DefaultRenderEmpty componentNameSelect /;先尝试调用用户提供的renderEmpty(Select)若返回空值再回退到默认实现。同样的renderEmpty?.(componentName)模式也出现在Table、List、Cascader、Transfer、TreeSelect、Mentions、Table过滤浮层等处因此这些组件的空状态都能被统一接管。三、示例代码逐段拆解示例完整代码位于 components/empty/demo/config-provider.tsx核心由三部分组成。1. 自定义空状态渲染函数const customizeRenderEmpty () ( div style{{ textAlign: center }} SmileOutlined style{{ fontSize: 20 }} / pData Not Found/p /div );这里的返回内容与Empty组件内部结构无关它是一个完全独立的 React 节点图标 文案。因为函数签名不关心componentName所以对所有组件统一生效如果你希望不同组件显示不同文案也可以利用该参数const customizeRenderEmpty (componentName: string) { if (componentName Table) return p暂无表格数据/p; return p暂无数据/p; };2. 用 Switch 控制全局开关const [customize, setCustomize] useState(true);配合Switch的checked/onChangecustomize为true时启用自定义空状态为false时还原为默认。这是官方示例演示“局部作用域”的典型手法——ConfigProvider可以任意嵌套内层配置只影响其子树。3. 挂载 ConfigProviderConfigProvider renderEmpty{customize ? customizeRenderEmpty : undefined} {/* Select / TreeSelect / Cascader / Transfer / Table / List */} /ConfigProvider注意renderEmpty{undefined}的写法当customize为false时显式传undefined让 Provider 回到“未定制”状态其子组件回落到各自的DefaultRenderEmpty默认实现。下面是一份可直接运行、注释更完整的等价示例与官方 demo 行为一致import React, { useState } from react; import { SmileOutlined } from ant-design/icons; import { Cascader, ConfigProvider, Divider, List, Select, Space, Switch, Table, Transfer, TreeSelect, } from antd; const customizeRenderEmpty () ( div style{{ textAlign: center }} SmileOutlined style{{ fontSize: 20 }} / pData Not Found/p /div ); const style: React.CSSProperties { width: 200 }; const App: React.FC () { const [customize, setCustomize] useState(true); return ( Switch unCheckedChildrendefault checkedChildrencustomize checked{customize} onChange{setCustomize} / Divider / ConfigProvider renderEmpty{customize ? customizeRenderEmpty : undefined} Space vertical style{{ width: 100% }} h4Select/h4 Select style{style} / h4TreeSelect/h4 TreeSelect style{style} treeData{[]} / h4Cascader/h4 Cascader style{style} options{[]} showSearch / h4Transfer/h4 Transfer / h4Table/h4 Table style{{ marginTop: 8 }} columns{[ { title: Name, dataIndex: name, key: name }, { title: Age, dataIndex: age, key: age }, ]} / h4List/h4 List / /Space /ConfigProvider / ); }; export default App;运行后你会看到打开开关时Table、List、Transfer、Cascader、TreeSelect、Select 的空状态全部变成“笑脸图标 Data Not Found”关闭开关时全部恢复为 ant-design 默认插画空状态。四、默认空状态的实现原理当不传renderEmpty时各组件会走DefaultRenderEmpty其逻辑在 components/config-provider/defaultRenderEmpty.tsx 中一目了然switch (componentName) { case Table: case List: return Empty image{Empty.PRESENTED_IMAGE_SIMPLE} /; case Select: case TreeSelect: case Cascader: case Transfer: case Mentions: return Empty image{Empty.PRESENTED_IMAGE_SIMPLE} className{${prefix}-small} /; case Table.filter: return null; // 空过滤结果由组件自身实现逻辑渲染 null default: return Empty /; }两个值得注意的源码细节表格 / 列表用的是简化版图片Empty.PRESENTED_IMAGE_SIMPLE是一张小尺寸 SVG区别于组件默认的Empty.PRESENTED_IMAGE_DEFAULT大插画。下拉类组件还额外加了${prefix}-smallclass 进一步缩小尺寸。因此你在 Table、Select 里看到的默认空状态本来就比单独使用Empty /更紧凑——这一点在全局替换时同样适用。Table.filter返回null过滤后无结果属于组件内部交互场景需要组件自己实现逻辑因此renderEmpty对此组件名返回null而非占位内容。这也是renderEmpty按componentName分流的意义所在。RenderEmptyHandler之所以默认不直接挂在ConfigContext上源码注释也给出了原因defaultRenderEmpty会引入与 Empty 组件的循环依赖见 components/config-provider/context.ts 中ConfigContext的创建处注释。因此renderEmpty从 Provider 侧注入由各业务组件在使用时显式读取并回退。五、覆盖关系与作用域边界进阶用法局部覆盖 vs 全局覆盖ConfigProvider是可嵌套的renderEmpty遵循“就近原则”离组件最近的 Provider 生效未设置renderEmpty的内层 Provider 不会清空外层配置。这是与 demo 中 Switch 切换逻辑一致的行为Provider 的配置本质上沿 React Context 向下传播业务代码可借此在应用外壳放一个全局定制在某个功能模块内再做局部差异化定制。何时不该用 renderEmptyrenderEmpty接管的是“组件内置的默认空状态”。如果你的场景只是渲染一个页面级占位应该直接使用Empty组件并定制其image、description、children等属性而renderEmpty更适用于“数据容器”类组件表格、列表、下拉等在无数据时自动呈现统一品牌空状态的需求。此外示例中 Switch 切换为undefined还原默认的方式也提示了另一种用法把某段 UI 移出定制作用域或把配置置为undefined即可精准恢复默认。单独定制 Empty 自身外观如果你需要让单独使用的Empty也保持统一风格可以分别定制其 props。关于Empty组件的完整属性如image、description、classNames、styles等及两个内置静态资源Empty.PRESENTED_IMAGE_SIMPLE/Empty.PRESENTED_IMAGE_DEFAULT参见 components/empty/index.en-US.md其内置 SVG 插画绘制在 components/empty/empty.tsx组件的渲染结构image / description / footer 三段式语义 DOM可查看 components/empty/index.tsx。六、测试与行为验证仓库为renderEmpty提供了专门的单元测试 components/config-provider/tests/renderEmpty.test.tsx覆盖了全部 8 个componentName场景it.each([ Table, Table.filter, List, Select, TreeSelect, Cascader, Transfer, Mentions, ])(should render %s empty, (componentName: any) { const { container } render(RenderEmpty componentName{componentName} /); expect(container.firstChild).toMatchSnapshot(); });测试断言表明除Table.filter返回空外其余组件均按默认实现渲染出对应的 Empty 快照当传入未匹配的componentName如not_match时回退到通用Empty /分支。配套快照位于components/config-provider/__tests__/__snapshots__/下可作为理解每种默认空状态 DOM 结构的参考。七、实战小结要让 ant-design 项目中所有内置数据组件共享同一套空状态视觉推荐套路是在应用顶层包一层ConfigProvider实现renderEmpty(componentName)函数统一返回品牌化的空状态节点图标、文案、操作按钮均可需要某组件特殊处理时利用componentName分流或在局部再包一层 Provider涉及组件过滤、搜索无结果等“非整表为空”的交互场景留意Table.filter这类由组件内部接管的分支想预览“开关切换”效果参考 config-provider.tsx 中Switch useState的做法将配置在自定义与undefined之间动态切换即可。这样仅靠一个配置入口即可让 Select、Table、Transfer、Cascader、TreeSelect、List、Mentions 等组件的空状态在全局保持一致无需逐组件逐个改造。【免费下载链接】ant-designAn enterprise-class UI design language and React UI library项目地址: https://gitcode.com/GitHub_Trending/an/ant-design创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考