ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Ant Design Radio 组件完全指南:单选项、Radio.Group 双向绑定与源码级实现剖析

Ant Design Radio 组件完全指南:单选项、Radio.Group 双向绑定与源码级实现剖析 Ant Design Radio 组件完全指南单选项、Radio.Group 双向绑定与源码级实现剖析【免费下载链接】ant-designAn enterprise-class UI design language and React UI library项目地址: https://gitcode.com/GitHub_Trending/an/ant-designRadio 是 Ant Designantd数据录入Data Entry组件家族中的核心单选控件用于从多个选项中选中唯一状态。本指南以仓库 components/radio/index.en-US.md 的官方 API 文档为骨架结合 radio.tsx、group.tsx、radioButton.tsx 与 context.ts 的源码实现与 官方示例 展开。读完你将掌握 Radio 的全部 API、受控/非受控用法、options与Radio.Button两种声明方式以及 antd 如何通过 Context 实现整组单选的底层原理。何时使用 RadioWhen To Use来自官方文档的使用指引非常明确Radio 适用于两条典型场景用于从多个候选项中选中唯一一个状态single state selection与 Select 相比Radio 的差异在于选项对用户完全可见因此用户可以方便地对选项进行比较——这也意味着 Radio 的选项数量不宜过多一旦选项密集到需要折叠就应当改用 Select。原文档还特别给出了一个官方推荐 vs 不推荐的写法对照体现了 Radio 组件的正确打开方式——优先使用Radio.Group的数据驱动写法// When use Radio.Group, recommended ✅ return ( Radio.Group value{value} options{[ { value: 1, label: A }, { value: 2, label: B }, { value: 3, label: C }, ]} / ); // Not recommended ‍♀️ return ( Radio.Group value{value} Radio value{1}A/Radio Radio value{2}B/Radio Radio value{3}C/Radio /Radio.Group );两者的最终渲染结果等价但options写法让数据与视图完全解耦选项数据可以来自服务端接口或常量数组代码更精简、更易维护。需要说明的是Radio.Group同样完整支持手写Radio子元素的复合组件写法如下方 demo 所示两种形式官方都维护并通过测试覆盖。Radio 核心 APIRadio支持与其兄弟组件 Checkbox 共享的一整套抽象 Checkbox props类型见 interface.ts 中继承自AbstractCheckboxProps的RadioProps常用完整参数表如下。Radio / Radio.Button 属性PropertyDescriptionTypeDefaultVersionGlobal ConfigcheckedSpecifies whether the radio is selectedbooleanfalse×classNamesCustomize class for each semantic structure inside the component. Supports object or function.RecordSemanticDOM, string|(info: { props }) RecordSemanticDOM, string-6.0.06.0.0defaultCheckedSpecifies the initial state: whether or not the radio is selectedbooleanfalse×disabledDisable radiobooleanfalse×stylesCustomize inline style for each semantic structure inside the component. Supports object or function.RecordSemanticDOM, CSSProperties|(info: { props }) RecordSemanticDOM, CSSProperties-6.0.06.0.0valueAccording to value for comparison, to determine whether the selectedany-×最基础的用法示例来自 basic.tsx单独的未选中 Radio 只是一颗空心圆点import React from react; import { Radio } from antd; const App: React.FC () RadioRadio/Radio; export default App;取值比较机制value 判选原理value列的说明写得很精炼——According to value for comparison, to determine whether the selected依据 value 进行比较以决定是否选中。在源码 radio.tsx 中可以看到当 Radio 处于Radio.Group内时其选中态不再由自身checked决定而是通过严格相等判断mergedChecked props.value groupContext.value动态推导if (groupContext) { radioProps.name groupContext.name; radioProps.onChange onChange; mergedChecked props.value groupContext.value; radioProps.disabled radioProps.disabled ?? groupContext.disabled; } if (hasChecked || groupContext) { radioProps.checked mergedChecked; }这解释了为什么值相同会成为整组 Radio 联动选中/取消选中的唯一判据也提醒开发者同组 Radio 的value必须保持唯一且类型一致否则会出现多个选项同时被判中的现象。Radio 实例方法Radio通过 ref 暴露焦点控制能力类型RadioRef直接复用rc-component/checkbox的CheckboxRefNameDescriptionblur()Remove focus移除焦点focus()Get focus获取焦点Radio.Group整组单选的状态容器Radio.Group用于包裹一组Radio统一管理当前选中值。核心参数如下表含版本号均取自当前仓库文档PropertyDescriptionTypeDefaultVersionblockOption to fit RadioGroup width to its parent widthbooleanfalse5.21.0buttonStyleThe style type of radio buttonoutline|solidoutlineclassNamesCustomize class for each semantic structure inside the component. Supports object or function.RecordSemanticDOM, string|(info: { props }) ...-6.0.0defaultValueDefault selected valueany-disabledDisable all radio buttonsbooleanfalsenameThenameproperty of allinput[typeradio]children. If not set, it will fallback to a randomly generated namestring-optionsSet children optionalstring[]|number[]|ArrayCheckboxOptionType-optionTypeSet Radio optionTypedefault|buttondefault4.4.0orientationOrientationhorizontal|verticalhorizontalsizeThe size of radio button stylelarge|medium|small-stylesCustomize inline style for each semantic structure inside the component. Supports object or function.RecordSemanticDOM, CSSProperties|(info: { props }) ...-6.0.0valueUsed for setting the currently selected valueany-verticalIf true, the Radio group will be vertical. Simultaneously existing withorientation,orientationtakes prioritybooleanfalseonChangeThe callback function that is triggered when the state changesfunction(e: Event)-options 选项对象CheckboxOptionTypeoptions数组的元素类型与 Checkbox 共享同一抽象类型这也是示例中从antd/es/checkbox导入CheckboxGroupProps的原因完整字段如下PropertyDescriptionTypeDefaultVersionlabelThe text used to display as the Radio optionstring-4.4.0valueThe value associated with the Radio optionstring|number|boolean-4.4.0styleThe style to apply to the Radio optionReact.CSSProperties-4.4.0classNameclassName of the Radio optionstring-5.25.0disabledSpecifies whether the Radio option is disabledbooleanfalse4.4.0titleAdds the Title attribute valuestring-4.4.0idAdds the Radio Id attribute valuestring-4.4.0onChangeTriggered when the value of the Radio Group changes(e: CheckboxChangeEvent) void-4.4.0requiredSpecifies whether the Radio option is requiredbooleanfalse4.4.0Group 的两种选项来源与优先级看 group.tsx 的实现可以得出明确的源码事实当且仅当options存在且长度大于 0 时options优先于 children 被渲染源码注释如果存在 options优先使用。对纯字符串/数字选项会自动生成 label 等于 value 的 Radio对对象选项则会完整透传disabled、title、style、className、id、required与单选项独立的onChange。完整用法见 radiogroup-options.tsximport React, { useState } from react; import type { RadioChangeEvent } from antd; import { Radio } from antd; const options [ { label: Apple, value: Apple }, { label: Pear, value: Pear }, { label: Orange, value: Orange, disabled: true }, // 单选项禁用 ]; const App: React.FC () { const [value, setValue] useState(Apple); const onChange ({ target: { value } }: RadioChangeEvent) setValue(value); return ( Radio.Group options{options} onChange{onChange} value{value} optionTypebutton buttonStylesolid / ); }; export default App;受控与非受控源码级解读Radio.Group的状态管理在 group.tsx 中通过useControlledState(defaultValue, customizedValue)实现传入value即为受控模式仅传defaultValue则进入非受控模式。值得注意的两个实现细节onChange 的触发条件onRadioChange会先取出event.target.value执行内部setValue并且仅在val ! lastValue值确实发生变化时才触发外部的onChange——重复点击已选中的选项不会产生多余回调事件冒泡链单个 Radio 的 onChange见 radio.tsx会先调用自身props.onChange?.(e)再调用groupContext?.onChange?.(e)从而把状态逐级汇聚到 Group。官方 Demo 实战模式仓库 demo 目录为每个交互形态提供了可直接运行的示例带debug标签的为内部调试用例不建议照搬进生产代码。以下按使用场景归类1. Radio.Group 基础分组手写Radio子元素作为 Group 内容的写法同样被完整支持每个Radio的value即参与整组判选。对应示例 radiogroup.tsx。2. Radio.Button 按钮风格与禁用将Radio.Button即视觉上的分段按钮放进Radio.Group即可得到 antd 经典的 button 型单选。按钮样式的边框观感由buttonStyleoutline默认描边与buttonStylesolid实心填充控制见 radiobutton.tsx 与 radiobutton-solid.tsximport { Flex, Radio } from antd; const App: React.FC () ( Flex vertical gapmedium {/* 默认 outline 风格 */} Radio.Group onChange{onChange} defaultValuea Radio.Button valueaHangzhou/Radio.Button Radio.Button valueb disabledShanghai/Radio.Button Radio.Button valuecBeijing/Radio.Button /Radio.Group {/* solid 实心风格 整组禁用 */} Radio.Group disabled defaultValuec buttonStylesolid Radio.Button valueaHangzhou/Radio.Button Radio.Button valuebShanghai/Radio.Button /Radio.Group /Flex );从源码看Radio.ButtonradioButton.tsx本质上是一个用RadioOptionTypeContextProvider向子树注入optionTypebutton再渲染Radio的薄封装单个Radio在消费该 Context 后radio.tsx切换自身prefixCls到radio-button前缀。这也解释了为何optionType是Radio.Group专有属性——在开发模式下直接给Radio传optionType会触发 antd 的 usage 级 dev warningradio.tsx。3. 纵向排列vertical / orientationRadio.Group 默认水平排列设vertical或orientationvertical即变为纵向堆叠。文档明确说明当vertical与orientation同时存在时以orientation为准该优先级在 group.tsx 的useOrientation(orientation, vertical)中实现最终通过追加${prefixCls}-group-vertical类名控制布局。纵向 复杂 label如内嵌 Input 动态展开的示例见 radiogroup-more.tsx。4. Block 撑满父容器宽度block5.21.0可让整个 Group 宽度撑满父容器适合移动端或整行可点场景见 radiogroup-block.tsxRadio.Group block options{options} defaultValueApple / Radio.Group block options{options} defaultValuePear optionTypebutton /5. 尺寸sizebutton 型单选支持large/medium默认/small三档尺寸见 size.tsx。值得补充的源码细节Group 不显式传size时会通过 config-provider 的useSize钩子继承 ConfigProvider 的全局尺寸上下文因此它与全站按钮、输入框的尺寸保持一致。6. name 与表单集成Radio.Group的name会统一注入到所有内部input[typeradio]上用于浏览器原生的 radio 分组语义。源码 group.tsx 显示当name未提供时若 Group 处于 Form.Item 中会自动基于字段路径toNamePathStr(formItemName)useId生成稳定的默认 name实现一组 Radio 共享同名 input的正确语义。在 Form 中使用 name 的完整示例见 radiogroup-with-name.tsx。从源码理解 Radio 的组件架构深入阅读仓库源码可以清晰还原 Radio 的复合组件compound component组织方式组合导出index.tsx 将内部InternalRadio挂上静态成员Radio.Group Group、Radio.Button Button并标记内部标识Radio.__ANT_RADIO true最终导出Radio.Group、Radio.Button与全部 TypeScript 类型两级 Contextcontext.ts 同时定义了RadioGroupContext携带onChange、value、disabled、name、optionType、block与RadioOptionTypeContext用于把 Group/Button 的形态传给深层 Radio。group.tsx 用useMemo缓存 context 值后通过RadioGroupContextProvider包裹 children从而驱动整组状态可访问性Group 容器默认roleradiogroup并透传aria-*/data-*属性pickAttrs(props, { aria: true, data: true })配合原生input[typeradio]保证键盘与读屏兼容生态集成单个 radio.tsx 内部消费了DisabledContext支持通过 ConfigProvider 全局禁用、FormItemInputContext在表单内自动追加-in-form-item样式类、useComponentConfig读取 ConfigProvider 全局 classNames/styles 配置这正是 API 表中 classNames/styles 支持 Global Config 的来源并用Wave组件为选中态提供点击水波纹动效、支持 RTL 布局切换。Semantic DOM 语义结构与 classNames/styles自 6.0.0 起Radio 支持通过classNames/styles精确定制组件内部各语义结构节点SemanticDOM其语义结构定义可见 interface.ts 中的RadioSemanticType包含三个节点语义节点对应 DOM / 作用root最外层label包装radio-wrappericon底层rc-component/checkbox绘制的圆圈/勾选图标radio 输入核心label选项文字所在spanradio-label三者的实际绑定位置可在 radio.tsx 的渲染逻辑中逐一验证。同时支持对象或函数两种传值形式——函数形式会收到{ props }便于根据 props如选中态、禁用态动态计算样式官方交互示例见 style-class.tsx语义结构总览示例见 _semantic.tsx。样式与 Design Token 定制Radio 的样式通过 css-in-js 在 style 目录中生成并接入 antd 的主题 token 体系。API 文档末尾通过自动生成的ComponentTokenTable列出了 Radio 的全部组件级 Design Token配合主题定制能力themetoken 或 ConfigProvidertheme配置即可全局调整 Radio 的选中主色、尺寸、间距等视觉变量。想要直观观察 token 效果可直接运行官方调试示例 component-token.tsx涉及描边/线框调试的还有 wireframe.tsx 与 badge.tsxdebug 示例。小结Radio 是 antd 中最能体现小而美工程哲学的组件之一对外它用Radio、Radio.Group、Radio.Button三个组合 API 覆盖了单选的全部形态——普通圆点、按钮分段、纵向排列、整组禁用/单选项禁用、纯数据驱动的options声明与受控/非受控状态对内它通过双 Context、值相等判选、useId生成表单 name、ConfigProvider 尺寸/禁用/全局语义配置的层层透传把一组 Radio 只允许一个选中值的语义收敛在极少的核心代码中。本仓库 components/radio 目录下的源码、demo 官方示例与 interface.ts 类型定义是继续深入的最佳一手资料。【免费下载链接】ant-designAn enterprise-class UI design language and React UI library项目地址: https://gitcode.com/GitHub_Trending/an/ant-design创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表