ant-design Message 组件消息时长控制实战:从单条 duration 到全局默认配置
2026/9/8 19:52:22 网站建设 项目流程

ant-design Message 组件消息时长控制实战:从单条 duration 到全局默认配置

【免费下载链接】ant-designAn enterprise-class UI design language and React UI library项目地址: https://gitcode.com/GitHub_Trending/an/ant-design

message是 ant-design 中最常用的全局反馈组件之一,而其duration参数决定了消息在屏幕上停留多久后自动消失。本文围绕 duration.md 这一官方示例文档展开,先讲清"默认 3 秒、可按条自定义为 10 秒"的基本用法,再深入 message 的源码与 API,覆盖duration: 0不自动关闭、静态方法与 Hook 三种调用形态、以及通过message.config/ ConfigProvider 设置全局默认时长等完整实战方案。读完本文,你将能精确控制任意一条消息的展示时长,并理解其计时机制背后的实现原理。

一、duration 是什么:默认 3 秒,单条消息可自定义

antd 的 message(全局提示)默认在出现3s后自动消失。文档示例components/message/demo/duration.md的中英文说明如下:

  • 中文:自定义时长10s,默认时长为3s
  • 英文:Customize message display duration from default3sto10s

这里的默认值并非"约定俗成",而是写死在源码中的常量。在 useMessage.tsx 中可以清楚看到:

const DEFAULT_OFFSET = 8; const DEFAULT_DURATION = 3; const DEFAULT_STACK_CONFIG = false;

其中DEFAULT_DURATION = 3即为消息默认展示时长(单位秒),在Holder组件的参数解构中作为兜底值使用:

duration = DEFAULT_DURATION,

随后该值被透传给底层渲染容器useRcNotification(来自@rc-component/notification),从而驱动每条消息的自动关闭计时器。

二、单条消息自定义时长:完整示例与调用姿势

配套示例 duration.tsx 展示了最推荐的 Hook 用法——将duration设为10,使该条成功消息在 10 秒后消失:

import React from 'react'; import { Button, message } from 'antd'; const App: React.FC = () => { const [messageApi, contextHolder] = message.useMessage(); const success = () => { messageApi.open({ type: 'success', content: 'This is a prompt message for success, and it will disappear in 10 seconds', duration: 10, }); }; return ( <> {contextHolder} <Button onClick={success}>Customized display duration</Button> </> ); }; export default App;

要点说明:

  1. message.useMessage()返回[messageApi, contextHolder],其中contextHolder必须渲染在组件树中(如示例中的<>内),上下文场景下的messageApi.open才能正常工作。
  2. durationArgsProps中"自动关闭的延时,单位秒"字段,类型为number(见 interface.ts),不传时回落到默认值3

三种常见调用形态

在 antd 中设置duration有灵活的多形态写法,对应参数类型定义可参考 interface.ts 的TypeOpen

  • 静态方法 + 位置参数(最简单):message.success(content, [duration], onClose)
  • 静态方法 + 配置对象:message.success({ content, duration, onClose })
  • Hook API:messageApi.open({ content, duration })messageApi.success({ content, duration })

从 index.zh-CN.md 的静态方法表格可以看到完整参数语义:

参数说明类型默认值
content提示内容ReactNode | config-
duration自动关闭的延时,单位秒。设为 0 时不自动关闭number3
onClose关闭时触发的回调函数function-

三、duration 设为 0:消息不自动关闭

duration有一个高频使用场景——设置0后消息将不自动关闭,必须由代码或用户交互触发关闭。官方加载示例 loading.tsx 与堆叠示例 stack.tsx 中都大量使用这一技巧,例如 loading 场景常写成:

messageApi.open({ type: 'loading', content: 'Loading...', duration: 0, // 不自动关闭,等待业务完成后再手动销毁 });

在对应测试中也能验证该语义:components/message/__tests__/hooks.test.tsx中出现多次duration: 0,配合手动hide()/destroy()关闭;index.test.tsx的用例也以duration: 0保证消息在测试流程中不被自动移除,从而精确断言其渲染与关闭行为。

duration使用false时同样代表不自动关闭,这一形态可见于 PureList.tsx 的类型定义duration?: number | false以及纯展示面板 PurePanel.tsx 中的duration={null}(静态渲染面板自身不参与计时)。

四、如何精确测量"多久关闭":手动关闭与 Promise 接口

当你不确定具体该设多少秒时,可配合onClose回调与 Promise 接口精确感知关闭时机:

// 方式一:onClose 回调 messageApi.open({ content: '10 秒后自动关闭', duration: 10, onClose: () => console.log('message closed'), }); // 方式二:then 接口(messageType 同时实现了 close 函数与 PromiseLike<boolean>) messageApi.open({ content: '10 秒后自动关闭', duration: 10 }).then(() => { console.log('message closed'); });

这一双重能力由 interface.ts 的MessageType体现:它既是PromiseLike<boolean>,又保留了可直接调用以主动关闭的(): void形态。实现上,useMessage.tsx 的wrapPromiseFn会在originOpen注册的onClose中执行resolve(),从而同时驱动自动关闭与手动关闭的 Promise 结算。

值得留意的一个重载细节:TypeOpen的第二个参数在传函数时会被识别为onClose而非 duration(见 useMessage.tsx):

if (isFunction(duration)) { mergedOnClose = duration; } else { mergedDuration = duration; mergedOnClose = onClose; }

因此message.success('hi', 10, () => {})表示"显示 10 秒后触发回调",而message.success('hi', () => {})则等价于"立刻手动关闭消息(duration 缺省),关闭时触发回调"。

五、全局统一时长:message.config 与 ConfigProvider

如果希望"所有消息统一展示 N 秒",就不必逐条传duration,可以通过两种全局方式配置。

5.1 静态方法 message.config

在入口处调用一次即可,例如 index.zh-CN.md 的官方示例:

message.config({ top: 100, // 消息距离顶部的位置 duration: 2, // 全局默认自动关闭延时(秒) maxCount: 3, // 最大显示数,超出时最早的消息被自动关闭 rtl: true, // 开启 RTL 模式 prefixCls: 'my-message', // 自定义类名前缀 });

duration对应的字段说明为"默认自动关闭延时,单位秒",默认值3。其实现位于 index.tsx 的setMessageGlobalConfig:配置被合并进defaultGlobalConfig后,会触发message?.sync?.()让全局 Holder 重新读取上下文;之后每条消息在打开时都会合并这份全局配置(见同文件taskQueue执行处{ ...defaultGlobalConfig, ...task.config }),单条配置优先覆盖全局值。

5.2 通过 ConfigProvider 组件级配置

在 React 树中,还可以在ConfigProvidermessage属性下统一注入全局默认时长,适用于需要随作用域切换配置的场景:

import { ConfigProvider } from 'antd'; <ConfigProvider message={{ duration: 5 }}> <App /> </ConfigProvider>

ConfigOptions完整字段(见 interface.ts)还包括topgetContainermaxCountrtlstackpauseOnHover等;其中与时长体验紧密相关的是pauseOnHover——默认为true(useMessage.tsx),即鼠标悬停在消息上时暂停自动关闭计时,移开后继续,可避免用户来不及阅读就被自动关闭。若需在单条消息上覆盖,ArgsProps同样暴露了pauseOnHover字段(interface.ts)。

六、源码视角:时长如何被消费

  • 常量定义与默认值:DEFAULT_DURATION = 3,见 useMessage.tsx。
  • 单条合并逻辑:Holder接收duration = DEFAULT_DURATION后透传给useRcNotification({ ..., duration }),见 useMessage.tsx。
  • 参数归一化:typeOpen(content, duration?, onClose?)或对象形态统一转换为ArgsProps,见 useMessage.tsx。
  • 自动关闭的计时与销毁由底层@rc-component/notification完成,antd 层只负责传入时长与透传关闭回调(onClose触发后resolve,见 useMessage.tsx)。

七、实践建议与注意事项

  1. 从 Hook API 起步:React 18 及以后版本中,静态方法在并发渲染场景存在上下文(ConfigProvider)丢失与render时序告警的风险,antd 官方推荐优先使用message.useMessage()获取实例再调用,示例 duration.tsx 采用的正是一致模式。
  2. 合理取值:信息性反馈建议 3 秒左右;需要用户记住的较重要提示可放宽到 5~10 秒(如本文示例的 10s);加载中、可交互或错误详情较长时用duration: 0配合手动关闭,避免消息自行消失导致信息丢失。
  3. 警惕全局配置作用域message.config是全局副作用,适合在应用入口设置;组件库/子应用内部建议用ConfigProvider message={{ duration }}做局部覆盖,避免污染宿主环境。
  4. 时长只对"自动关闭"生效:无论duration设为何值,消息的key去重、destroy()maxCount溢出淘汰等机制都独立于计时器运行,测试与联调时可用duration: 0锁定消息存在时间,再对行为做精确断言。

通过单条duration与全局配置的组合,antd 的 message 组件足以覆盖从"一闪而过的轻提示"到"需用户确认的持久提示"的完整产品需求,这也是官方文档将其列为独立 demo 的原因所在。

【免费下载链接】ant-designAn enterprise-class UI design language and React UI library项目地址: https://gitcode.com/GitHub_Trending/an/ant-design

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询