ant-design Modal 按钮文案定制全指南:okText / cancelText 与多语言 locale 机制详解
在 ant-design 的 Modal 组件中,"确认 / 取消"这类操作按钮的默认文案来自全局 locale(语言包),但很多业务场景需要按对话框单独定制,例如中文界面的"确定 / 取消"、审批场景的"同意 / 驳回"、单按钮场景的"知道了"等。官方组件演示 components/modal/demo/locale.md 给出的核心答案非常简洁:设置 okText 与 cancelText 即可自定义按钮文字。
本指南将以该演示为入口,结合 Modal 源码与多语言机制,讲清楚三件事:如何在受控 <Modal> 与命令式 modal.confirm(...) 两种形态下定制按钮文案;这些文案的默认值与解析优先级;以及借助 ConfigProvider locale 与 changeConfirmLocale 从全局层面定制文案的完整做法。读完你可以直接在真实项目中落地"按对话框/按全局维度自定义按钮文字"的需求。
Demo 场景速览:两种定制按钮文字的写法
locale.md 对应的完整示例代码位于 components/modal/demo/locale.tsx,它同时演示了 ant-design Modal 提供的两种调用形态下的文案定制。
形态一:受控 <Modal> 上直接传 okText / cancelText
import React, { useState } from 'react';
import { Button, Modal } from 'antd';
const LocalizedModal = () => {
const [open, setOpen] = useState(false);
const showModal = () => setOpen(true);
const hideModal = () => setOpen(false);
return (
<>
<Button type="primary" onClick={showModal}>
Modal
</Button>
<Modal
title="Modal"
open={open}
onOk={hideModal}
onCancel={hideModal}
okText="确认"
cancelText="取消"
>
<p>Bla bla ...</p>
<p>Bla bla ...</p>
<p>Bla bla ...</p>
</Modal>
</>
);
};
关键点:Modal 通过 open 受控显示,点击确定 / 取消按钮后分别触发 onOk / onCancel;okText="确认"、cancelText="取消" 直接覆盖默认按钮文案。此时对话框底部仍保留默认的"双按钮"结构(取消 + 确定)。
形态二:命令式 API(Modal.useModal() / 静态方法)中传 okText / cancelText
import { ExclamationCircleOutlined } from '@ant-design/icons';
import { Button, Modal, Space } from 'antd';
const App: React.FC = () => {
const [modal, contextHolder] = Modal.useModal();
const confirm = () => {
modal.confirm({
title: 'Confirm',
icon: <ExclamationCircleOutlined />,
content: 'Bla bla ...',
okText: '确认',
cancelText: '取消',
});
};
return (
<>
<Space>
<LocalizedModal />
<Button onClick={confirm}>Confirm</Button>
</Space>
{contextHolder}
</>
);
};
这里演示了 Modal.useModal() 这套 hooks 形态:调用 modal.confirm(config) 会返回一个 Promise 风格的命令式确认框,config 中同样支持 okText、cancelText。注意必须把 modal.confirm() 返回的 contextHolder 渲染在组件树中,以保证弹窗能够获得正确的 React Context(locale、主题等)。同一套参数对象同样适用于静态方法 Modal.confirm、Modal.info、Modal.success、Modal.error、Modal.warning,它们的类型统一定义为 ModalFuncProps,见 components/modal/interface.ts。
类型定义:okText / cancelText 不止支持字符串
打开 components/modal/interface.ts 可以看到,普通受控形态下 ModalProps 中两处定义:
/** Text of the OK button */
okText?: React.ReactNode;
/** Text of the Cancel button */
cancelText?: React.ReactNode;
两个字段的类型均为 React.ReactNode 而非 string,这意味着你不仅能传普通文本,还可以传入图标、带样式的 JSX 元素,例如 <Space><CheckOutlined /> 同意</Space>。同理,ModalFuncProps(命令式 / 静态方法使用的配置类型)也声明了相同的 okText、cancelText 字段(见 interface.ts)。
同文件还定义了整个 Modal 的 locale 数据结构 ModalLocale(interface.ts):
export interface ModalLocale {
okText: string;
cancelText: string;
justOkText: string;
}
三个字段的分工是:
| 字段 | 语义 | zh-CN 默认值 | en-US 默认值 |
|---|---|---|---|
okText |
双按钮场景下"确定"按钮文案 | 确定 | OK |
cancelText |
双按钮场景下"取消"按钮文案 | 取消 | Cancel |
justOkText |
仅单个 OK 按钮时的文案(见下文 confirm 差异) | 知道了 | OK |
默认语言包来源为 components/locale/zh_CN.ts 与 components/locale/en_US.ts。
深入原理:文案解析优先级与 justOkText 的分流逻辑
传了 okText 会覆盖 locale;不传则回落到当前语言包。这一"显式传值优先、locale 兜底"的逻辑在两个关键源码文件中各有体现。
普通 Modal 底部按钮:Footer 组件的兜底取值
普通 <Modal> 的默认底部由 components/modal/shared.tsx 中的 Footer 组件负责渲染:
const [locale] = useLocale('Modal', getConfirmLocale());
// ================== Locale Text ==================
const okTextLocale: React.ReactNode = okText || locale?.okText;
const cancelTextLocale = cancelText || locale?.cancelText;
也就是说:okText 非空就直接采用用户传入值,否则取 useLocale('Modal', ...) 拿到的语言包字段。得到的 okTextLocale / cancelTextLocale 会连同 confirmLoading、okButtonProps 等一起通过 ModalContextProvider 注入 Context,最终由底部按钮组件读取渲染(NormalOkBtn / NormalCancelBtn 对应普通形态;确认框则使用 ConfirmOkBtn / ConfirmCancelBtn)。
确认类弹窗:okCancel 决定用 okText 还是 justOkText
命令式 Modal.confirm / Modal.info 等确认对话框走的是 components/modal/ConfirmDialog.tsx,它有一个值得注意的差异逻辑:
// 默认为 true,保持向下兼容(type 为 'confirm' 时展示双按钮)
const mergedOkCancel = okCancel ?? type === 'confirm';
// ================== Locale Text ==================
const okTextLocale = okText || (mergedOkCancel ? mergedLocale?.okText : mergedLocale?.justOkText);
const cancelTextLocale = cancelText || mergedLocale?.cancelText;
- 对
type: 'confirm'(或显式设置okCancel: true),展示"取消 + 确定"双按钮,OK 按钮默认文案来自ModalLocale.okText; - 对
info / success / error / warning这类默认只有一个 OK 按钮的弹窗(okCancel为 false),OK 按钮文案取的是justOkText——这正是中文语言包里justOkText: '知道了'的用武之地。
所以如果你看到 Modal.success 之类弹窗的按钮显示"知道了"而不是"确定",这是设计行为而非 bug。若希望这类弹窗也显示"确定"并带取消按钮,可以传 okCancel: true,或直接传 okText 显式覆盖。
locale 兜底值从哪里来:useLocale 的合并逻辑
源码中的 useLocale('Modal', getConfirmLocale()) 定义在 components/locale/useLocale.ts:它从 LocaleContext 读取 ConfigProvider 注入的语言包,再与默认 locale 做浅合并——ConfigProvider 中配置的 locale.Modal 会覆盖默认值,而用户传入组件的 okText 又优先于两者,最终形成"组件 props > ConfigProvider locale > 组件默认 locale"的优先级链。
全局定制:用 ConfigProvider 一次改完全站 Modal 按钮文案
如果希望整个应用的 Modal 按钮统一使用自定义文案(例如统一改为"好 / 算了"),无需在每个 Modal 上重复传参,只要在根部配置 locale:
import zhCN from 'antd/locale/zh_CN';
import { ConfigProvider } from 'antd';
<ConfigProvider
locale={{
...zhCN,
Modal: { okText: '好', cancelText: '算了', justOkText: '知道了' },
}}
>
<App />
</ConfigProvider>
由于 useLocale 会从 LocaleContext 读取 Modal 配置并与组件默认值合并,这种覆盖会作用于树内所有未显式传 okText / cancelText 的 Modal 与确认框。更常见的做法是直接用 antd/locale/zh_CN 或 antd/locale/en_US 等整套语言包,再按需展开覆盖其中 Modal 片段。
运行时动态修改:changeConfirmLocale
ant-design 还为 Modal 保留了非 React 运行时修改的能力:组件包内的 components/modal/locale.ts 暴露了 changeConfirmLocale(newLocale) 与 getConfirmLocale():
changeConfirmLocale(modalLocale):压入一份新的ModalLocale并重新生成全局运行时 locale,返回一个 cleanup 函数,调用它即可撤销修改;- 传入
undefined则恢复为en_US内置默认; - 底层通过维护
localeList数组、以reduce合并所有注入片段实现叠加覆盖。
该 API 主要用于在 React 树之外(如静态方法调用路径)兜底,业务上更推荐优先使用 ConfigProvider。components/modal/shared.tsx 中把 getConfirmLocale() 作为 useLocale 的默认值传入,正是为了让静态弹窗在没有 ConfigProvider 包裹时仍能拿到一份合理的默认文案。
相关延伸:从文案到按钮行为的完整控制
- 按钮类型:配合
okType(如'danger')可把确定按钮变为主按钮之外的样式类型,见 interface.ts。 - 按钮 Props:
okButtonProps、cancelButtonProps可传入 disabled、loading、className 等原生 Button 属性,实现"提交中禁用取消"等交互。 - 自定义整条底部:
footer={null}隐藏默认按钮,footer={(originNode, { OkBtn, CancelBtn }) => ...}完全接管底部渲染——此时OkBtn/CancelBtn渲染器仍会读取 Context 中解析好的okTextLocale等文案值,定制按钮文字与完全自定义 footer 可以并存。
小结
围绕 okText / cancelText,ant-design 提供了一条清晰的定制路径:组件级直接传 props(两者均为 React.ReactNode,且优先级最高);应用级通过 ConfigProvider 的 locale.Modal 覆盖;运行时级使用 changeConfirmLocale 做非 React 形态的临时切换。同时请留意确认框的三文案模型 okText / cancelText / justOkText:单按钮类型弹窗默认取 justOkText,需要"确定"双按钮文案时用 okCancel: true 或显式 okText 即可。掌握这几点,就能在不同业务场景下精准控制 Modal 每一个按钮的文案与交互。
更多细节可继续查看本仓库中的示例源码 components/modal/demo/locale.tsx、类型与默认文案 components/modal/interface.ts、普通底部渲染 components/modal/shared.tsx、确认框文案分流 components/modal/ConfirmDialog.tsx 以及语言包接入 components/locale/useLocale.ts。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0626
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00