Ant Design Notification 消息堆叠(Stack)功能详解:threshold 阈值与自动收起配置实战
【免费下载链接】ant-designAn enterprise-class UI design language and React UI library项目地址: https://gitcode.com/GitHub_Trending/an/ant-design
本篇文章聚焦 Ant Design 组件库中 Notification 通知提醒框的**消息堆叠(Stack)**能力,围绕 stack 示例文档 展开:介绍其默认行为、threshold阈值触发规则、折叠后最多展示 3 条消息的行为,以及如何通过配置开关堆叠。读完本文你将掌握 hook 与配置 API 两种方式下的完整参数语义、默认值来源与源码实现原理,可直接复现示例进行调参验证。
一、什么是消息堆叠:为什么通知框需要"叠起来"
Notification 常用于批量推送运行状态,当短时间连续弹出多条消息时,若每一条都完整平铺,会同时遮挡页面右侧大量内容,且视觉上难以追踪新消息。堆叠(Stack)机制正是为解决这一体验问题而生:默认开启,当同时存在的通知数量超过配置的threshold阈值后,多余消息会被自动收起,仅保留最多 3 条消息的折叠态,避免通知面板无限堆高。
这与 antd 中 Notification 提供的另一个容量控制手段maxCount(限制容器最多渲染多少条)不同:堆叠收起的消息仍然存在,只是以紧凑折叠样式呈现,等待用户展开或逐条关闭;而maxCount会直接销毁超出数量的消息。从本 demo 对应的实现看,堆叠更多是"视觉收纳",而非"数量裁剪"。
二、示例整体体验:阈值、开关与触发按钮
源码 components/notification/demo/stack.tsx 用一个完整可交互页面演示了堆叠的核心玩法:
- Enabled 开关:通过
Switch在"启用堆叠(传入 stack 配置对象)"与"禁用堆叠(传入false)"之间切换; - Threshold 数字输入:
InputNumber设置触发堆叠的数量阈值,min={1}、max={10}、step={1},未启用堆叠时该输入框置灰(disabled={!enabled}); - 触发按钮:点击 "Open the notification box" 逐条弹出内容随机(1~5 行)的通知,其中
duration: false让消息不自动关闭,从而方便在同一时间窗口内累积观察堆叠效果。
const [enabled, setEnabled] = React.useState(true); const [threshold, setThreshold] = React.useState(3); const [api, contextHolder] = notification.useNotification({ stack: enabled ? { threshold, } : false, }); const openNotification = () => { api.open({ title: 'Notification Title', description: '...', duration: false, }); };该示例通过官方文档的 demo 标签标注为v5.10.0引入(见 components/notification/index.en-US.md 中version="5.10.0"标记),意味着从该版本起stack配置正式可用。按官方中文说明,折叠状态下面板最多展示 3 个消息,这是一个固定上限,与threshold的取值相互配合:threshold决定"达到多少条开始收起",3 条则是"收起后仍露出的上限"。
三、stack 配置参数:类型、默认值与取值语义
在 antd 的 Notification 类型定义 components/notification/interface.ts 中,stack字段的签名是:
stack?: boolean | { threshold?: number };对应官方 API 文档表格(components/notification/index.en-US.md)中的完整定义如下:
| 属性 | 说明 | 类型 | 默认值 | 版本 |
|---|---|---|---|---|
stack | 当消息数量超过阈值时启用堆叠收起 | boolean \| { threshold: number } | { threshold: 3 } | 5.10.0 |
取值语义可以归纳为三种形态:
- 不传(
undefined):等价于默认配置{ threshold: 3 },堆叠默认开启; - 布尔值
false:完全关闭堆叠,所有消息保持完整平铺展开;true则使用默认阈值; - 对象
{ threshold: number }:自定义触发堆叠的数量阈值,例如设为 5,表示第 6 条消息出现时开始收起。
结合官方文档另一处说明可以推断设计取舍:Notification 为了保持堆叠卡片样式的一致性,采用了固定宽度布局,因此通知外层节点上并不支持max-content、min-content、fit-content(...)这类由内容决定的固有宽度(intrinsic width)。这一点在使用自定义样式时需特别注意——试图通过固有宽度让通知"自适应内容"会与堆叠机制冲突。
四、示例之外:堆叠配置在代码层面的默认值与合并逻辑
默认值并非threshold: 3这么简单
在 components/notification/useNotification.tsx 中定义了常量:
const DEFAULT_STACK_CONFIG = { offset: 8 };也就是说,useNotification/notification.config的"默认堆叠配置"内部还包含offset: 8(折叠堆中相邻消息之间的间距为 8px)。官方 API 文档表格中的默认值{ threshold: 3 }与代码中的{ offset: 8 }来自不同层级:threshold的兜底语义由 rc-component 内部处理,而 antd 层通过DEFAULT_STACK_CONFIG提供间距等兜底项。理解这一点有助于排查"默认行为和文档描述不完全一致"的困惑。
useStackConfig:配置的三态合并
antd 通过 Hook components/notification/hooks/useStackConfig.ts 完成用户配置与默认配置的合并,其入参类型为:
export type StackConfigInput = boolean | StackConfig | undefined;合并逻辑值得逐条拆解:
stackConfig ?? defaultStackConfig:用户未传(undefined)时回落为默认配置,保证"默认开启";- 若合并结果为
false或空值,直接返回false,即禁用堆叠; - 否则将默认配置与用户配置浅合并(先展开默认对象,再覆盖用户对象,均在
isPlainObject校验通过的前提下),支持未来在默认层加入更多字段而无需改动外部 API。
随后在 components/notification/useNotification.tsx 中调用useStackConfig(stack, DEFAULT_STACK_CONFIG)得到最终配置,并原样透传给底层@rc-component/notification的useRcNotification(stack: stackConfig)。因此用户可以放心使用"局部覆盖"的写法:只传{ threshold: 6 },offset: 8依然生效。
静态 API 同样受控
除了 demo 使用的 Hook 形式notification.useNotification({ stack }),静态调用notification.open/notification.info等全局实例同样支持通过notification.config({ stack })应用全局配置。从 components/notification/index.tsx 的实现看,全局实例由内部调用useInternalNotification的GlobalHolder承载,stack会随全局配置一并同步到渲染实例,因此两种接入方式下堆叠行为一致。
五、真实运行效果:快速复现与验证
为快速复现"超过阈值后收起"的效果,建议直接照搬 demo 的要点:设置duration: false让通知保持不消失,连续点击 5 次以上触发按钮,观察面板变化:
- 前
threshold(默认 3)条通知完整展开排列; - 第
threshold + 1条出现后,多余消息折叠,面板最终只露出约 3 条量级的紧凑视图; - 将 Threshold 调到 1 并再触发,可见几乎任何新消息都会立即触发折叠——数值越小越"敏感";
- 关闭 Enabled 开关后,全部消息恢复完整平铺展示,验证
stack: false的效果。
其中InputNumber的取值范围(1~10)只是 demo 界面的交互约束,并非 API 上限;实际传任意正整数皆可,但小于等于折叠展示上限(3)时,折叠行为会在极少数消息时就被触发,这与 demo 默认值为 3 的设置形成了"阈值与折叠上限一致"的最典型演示场景。
六、测试佐证:禁用堆叠的正确姿势
antd 对stack: false的禁用路径有明确的单元测试覆盖,见 components/notification/tests/hooks.test.tsx:
it('disable stack', () => { const Demo = () => { const [api, holder] = notification.useNotification({ stack: false }); React.useEffect(() => { api.info({ title: null, description: 'test' }); }, []); return holder; }; render(<Demo />); expect(document.querySelector('.ant-notification-stack')).toBeFalsy(); });该用例断言:当配置stack: false后,即使消息已成功弹出,DOM 中也不会出现.ant-notification-stack容器,从渲染层验证了禁用分支真实生效。相应地,demo 快照测试 components/notification/tests/snapshots/demo.test.ts.snap 与demo-extend.test.ts.snap中也包含stack.tsx的渲染快照,说明该交互示例持续作为回归用例被 CI 守护。
七、小结:何时该用堆叠
- 业务中存在高频、连续、短时间并发的通知推送(如构建任务状态、上传进度、操作批量结果)时,建议保持默认堆叠开启,并用合适
threshold平衡"完整可见"与"遮挡干扰"; - 若每条通知信息量大、需要并排比对,可显式
stack: false关闭,换取完整平铺; - 自定义
stack: { threshold }时注意与折叠上限 3 的配合,并结合固定宽度布局的限制设计样式。
核心结论一句话:Notification 的stack默认开启,threshold(默认 3)负责决定"何时收起",折叠后最多露出 3 条消息,false可整体关闭该机制。动手运行 stack demo,将开关与阈值拖动观察,是理解该特性最直观的方式。
【免费下载链接】ant-designAn enterprise-class UI design language and React UI library项目地址: https://gitcode.com/GitHub_Trending/an/ant-design
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考