ARTICLE DETAIL

建站实战干货

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

react-admin `<CheckboxGroupInput>` 组件完全指南:多选输入的配置、源码与实战

2026/9/21 0:27:48 拓冰建站 浏览量
react-admin `<CheckboxGroupInput>` 组件完全指南:多选输入的配置、源码与实战 react-adminCheckboxGroupInput组件完全指南多选输入的配置、源码与实战【免费下载链接】react-adminA frontend Framework for single-page applications on top of REST/GraphQL APIs, using TypeScript, React and Material Design项目地址: https://gitcode.com/gh_mirrors/re/react-adminCheckboxGroupInput是 react-admin 表单体系中用于编辑「标量值数组」的核心输入组件它将所有候选选项以复选框组的形式一次性展示给用户特别适合角色分配、多标签、多分类等场景。本文以官方文档为骨架结合仓库内 ra-ui-materialui 与 ra-core 的实际源码与测试用例系统讲解其用法、全部 Props、与关系型资源ReferenceArrayInput的集成方式以及底层渲染与值解析原理帮助你在真实项目中正确、高效地使用该组件。组件定位在「全部可见」与「多选数组」之间架桥当表单需要用户从一组候选值中勾选多个值时CheckboxGroupInput是默认推荐方案它把所有可能取值平铺展示用户一目了然、即点即选。它编辑的表单值是一个标量数组例如{ id: 123, name: John Doe, roles: [u001, u003], }react-admin 还提供了其他可编辑数组值的输入组件按交互形态区分TextArrayInput直接编辑字符串数组SelectArrayInput下拉多选适合候选值较多的场景AutocompleteArrayInput带搜索过滤的多选自动完成输入DualListInput在两个列表之间移动选项的双列选择器。如果你的值是内嵌对象数组如[{ id: 123, title: Hello }, { id: 456, title: World }]则应改用ArrayInput。选择依据很直观候选集小且需要全部可见时用CheckboxGroupInput候选集大或需要搜索时用下拉/自动完成类组件。基本用法除了所有输入组件共有的source之外CheckboxGroupInput还强制要求一个choicesprop 来声明候选值列表import { CheckboxGroupInput } from react-admin; CheckboxGroupInput sourceroles choices{[ { id: admin, name: Admin }, { id: u001, name: Editor }, { id: u002, name: Moderator }, { id: u003, name: Reviewer }, ]} /默认情况下组件从choices构建选项时使用id字段作为选项的值option valuename字段作为选项的显示文本option text。因此source对应的表单值必须是所选值的数组例如roles: [u001, u003]。这一点在源码的useChoices中也有对应默认值体现见 useChoices.tsxoptionText默认name、optionValue默认id、translateChoice默认true。Props 一览PropRequiredTypeDefaultDescriptionchoicesRequiredObject[]-候选值列表labelPlacementOptionalbottom|end|start|topend复选框标签的位置optionsOptionalObject-透传给 Material UICheckbox组件的 propsoptionTextOptionalstring|Function|ReactElementname用于显示选项文本的字段名、渲染函数或 React 元素optionValueOptionalstringid用作输入值的字段名rowOptionalbooleantrue是否在紧凑的一行内展示选项组translateChoiceOptionalbooleantrue是否翻译选项文本disableValueOptionalstringdisabled用于标记禁用选项的自定义字段名CheckboxGroupInput同时接受通用输入组件的全部 Props如label、helperText、validate、disabled、readOnly、fullWidth、format、parse等。从 CheckboxGroupInput.tsx 的类型定义可以确认其 Props 类型为CommonInputProps、ChoicesProps、Material UICheckboxProps与FormControlProps的组合。choices候选值列表的多种形态choices必须是对象数组每个对象代表一个候选选项其中id是值、name是展示给用户的标签CheckboxGroupInput sourceroles choices{[ { id: admin, name: Admin }, { id: u001, name: Editor }, { id: u002, name: Moderator }, { id: u003, name: Reviewer }, ]} /自定义 label 与 value 字段如果候选对象用于标签和值的属性名不是name/id通过optionText和optionValue指定CheckboxGroupInput sourceroles choices{[ { _id: admin, label: Admin }, { _id: u001, label: Editor }, { _id: u002, label: Moderator }, { _id: u003, label: Reviewer }, ]} optionValue_id optionTextlabel /源码对optionValue的取值支持点号路径lodash 的get测试用例 CheckboxGroupInput.spec.tsx 验证了optionValuefoobar.id配合choices{[{ foobar: { id: foo }, name: Bar }]}时复选框 value 为foo。optionText同样支持点号路径例如optionTextfoobar.name。禁用某些选项通过在某个候选对象上设置disabled: true即可将该选项渲染为禁用态const choices [ { id: tech, name: Tech }, { id: lifestyle, name: Lifestyle }, { id: people, name: People, disabled: true }, ]; CheckboxGroupInput sourcecategory choices{choices} /底层实现在 CheckboxGroupInputItem.tsxgetDisableValue(choice)读取disableValue指定字段并传给Checkbox disabled{disabled}测试用例也验证了禁用项与普通项的disabled属性差异见 CheckboxGroupInput.spec.tsx。翻译选项默认开启choices默认会被翻译因此可以直接把翻译 key 作为显示文本const choices [ { id: admin, label: myroot.roles.admin }, { id: u001, label: myroot.roles.u001 }, { id: u002, label: myroot.roles.u002 }, { id: u003, label: myroot.roles.u003 }, ];翻译逻辑位于 useChoices.tsx文本会经过translate(String(choiceName), { _: choiceName })处理——即能找到翻译则显示译文找不到则回退显示原始字符串。若需要关闭翻译设置translateChoice{false}详见下文translateChoice一节。从其他资源获取选项如果选项需要从另一个资源实时拉取那么你实际在编辑一个一对多或多对多关系。此时应把CheckboxGroupInput放进ReferenceArrayInput或ReferenceManyToManyInput中无需再写choices——父组件会根据关联资源的可能值自动注入ReferenceArrayInput sourcetag_ids referencetags CheckboxGroupInput / /ReferenceArrayInput字符串数组作为 choiceschoices也支持纯字符串数组等价于自动映射为{ id: value, name: value }const roles [Admin, Editor, Moderator, Reviewer]; CheckboxGroupInput sourceroles choices{roles} / // 等价于 const choices roles.map(value ({ id: value, name: value })); CheckboxGroupInput sourceroles choices{choices} /这一转换在 useChoicesContext.ts 中实现isArrayOfStrings检测到全字符串数组后convertOptionsToChoices将其映射为{ id, name }对象数组。CheckboxGroupInput在 Storybook 中也提供了StringChoices演示场景见 CheckboxGroupInput.stories.tsx。labelPlacement标签位置默认每个选项的标签显示在复选框右侧。通过labelPlacement可以改为bottom、start、topCheckboxGroupInput sourceoptions choices{choices} labelPlacementbottom /该 prop 直接透传给 Material UI 的FormControlLabel见 CheckboxGroupInputItem.tsx。options透传 Material UI Checkbox 属性如果希望覆盖 Material UICheckbox的任何属性通过options对象传入例如自定义图标import { FavoriteBorder, Favorite } from mui/icons-material; CheckboxGroupInput sourceoptions options{{ icon: FavoriteBorder /, checkedIcon: Favorite / }} /从源码可以看到options被展开到每个Checkbox上见 CheckboxGroupInputItem.tsx类型为CheckboxProps因此 Material UI 官方 Checkbox 文档中的所有属性如color、size、disableRipple等均可使用。optionText定制选项显示文本默认使用name字段作为选项文本可通过optionText覆盖const choices [ { id: admin, label: Admin }, { id: u001, label: Editor }, { id: u002, label: Moderator }, { id: u003, label: Reviewer }, ]; CheckboxGroupInput sourceroles choices{choices} optionTextlabel /与 ReferenceArrayInput 搭配当choices来自ReferenceArrayInput或ReferenceManyToManyInput时optionText尤其有用默认情况下 react-admin 使用资源的recordRepresentation函数来生成记录标签但显式设置optionText后优先生效ReferenceArrayInput sourcetag_ids referencetags CheckboxGroupInput optionTexttag / /ReferenceArrayInput源码中这一优先级逻辑位于 CheckboxGroupInput.tsxoptionText ?? (isFromReference ? getRecordRepresentation : name)即显式optionText最优先其次是从引用上下文获取的recordRepresentation最后才是默认的name。测试用例 CheckboxGroupInput.spec.tsx 验证了在ReferenceArrayInput内默认使用recordRepresentation渲染标签Option 1 (This is option 1)。函数形式的 optionTextoptionText也可以是一个接收整个 choice 对象、返回显示文本的函数const choices [ { id: 123, first_name: Leo, last_name: Tolstoi }, { id: 456, first_name: Jane, last_name: Austen }, ]; const optionRenderer choice ${choice.first_name} ${choice.last_name}; CheckboxGroupInput sourceauthors choices{choices} optionText{optionRenderer} /React 元素形式的 optionTextoptionText还可以是 React 元素它会被渲染在RecordContext内并以对应 choice 作为record因此内部可以直接使用 Field 组件const choices [ { id: 123, first_name: Leo, last_name: Tolstoi }, { id: 456, first_name: Jane, last_name: Austen }, ]; const FullNameField () { const record useRecordContext(); return span{record.first_name} {record.last_name}/span; } CheckboxGroupInput sourceauthors choices{choices} optionText{FullNameField /}/该能力由 useChoices.tsx 实现当optionText是合法 React 元素时用RecordContextProvider包裹该元素后渲染。测试用例 CheckboxGroupInput.spec.tsx 与 Storybook 的OptionText场景见 CheckboxGroupInput.stories.tsx都展示了这种多行富文本选项的用法。optionValue定制选项值字段默认使用id作为选项值可通过optionValue改为其他字段const choices [ { _id: admin, name: Admin }, { _id: u001, name: Editor }, { _id: u002, name: Moderator }, { _id: u003, name: Reviewer }, ]; CheckboxGroupInput sourceroles choices{choices} optionValue_id /注意optionValue仅在通过choicesprop 直接提供选项时生效。当CheckboxGroupInput用在ReferenceArrayInput内部时optionValue恒为id——因为此时选项是关联资源拉取到的记录而记录应当始终拥有id字段。row一行展示还是每行一个默认所有复选框横向排成一行设置row{false}后每个选项独占一行CheckboxGroupInput sourceoptions choices{choices} row{false} /该 prop 透传给 Material UIFormGroup的row属性见 CheckboxGroupInput.tsx。选项较少、适合一行展示时保持默认即可选项文本较长或多语言场景下建议row{false}。sxCSS APICheckboxGroupInput接受常规classNameprop也支持用sx覆盖内部组件样式语法与示例见 sx 文档。支持以下子类Rule nameDescription .RaCheckboxGroupInput-label应用于底层 Material UIFormLabel组件如需通过应用级样式覆盖统一定制所有CheckboxGroupInput实例使用RaCheckboxGroupInput作为覆盖 key。源码在 CheckboxGroupInput.tsx 中注册了RaCheckboxGroupInput主题组件名及其root/label/helperText三个可覆盖类。translateChoice关闭选项翻译选项文本默认经过翻译因此可直接使用翻译 keyconst choices [ { id: admin, name: myroot.roles.admin }, { id: u001, name: myroot.roles.u001 }, { id: u002, name: myroot.roles.u002 }, { id: u003, name: myroot.roles.u003 }, ];但在某些场景例如放在ReferenceArrayInput内部时你可能不希望翻译选项文本此时设置translateChoice{false}CheckboxGroupInput sourceroles choices{choices} translateChoice{false}/有意思的是源码为「是否默认翻译」注入了上下文感知当组件位于引用输入内isFromReference为 true时默认值变为false见 CheckboxGroupInput.tsxtranslateChoice ?? !isFromReference避免把记录文本当作翻译 key 处理。测试用例 CheckboxGroupInput.spec.tsx 分别验证了默认翻译与translateChoice{false}时原文显示两种行为。disableValue自定义禁用标记字段默认读取选项对象中的disabled: true来渲染禁用态const choices [ { id: tech, name: Tech }, { id: lifestyle, name: Lifestyle }, { id: people, name: People, disabled: true }, ]; CheckboxGroupInput sourcecategory choices{choices} /若想改用其他字段标记禁用设置disableValueconst choices [ { id: tech, name: Tech }, { id: lifestyle, name: Lifestyle }, { id: people, name: People, not_available: true }, ]; CheckboxGroupInput sourcecategory choices{choices} disableValuenot_available /从引用资源拉取选项Fetching Choices如果要让choices来自一组关联记录用ReferenceArrayInput包裹CheckboxGroupInput并保持choices为空import { ReferenceArrayInput } from react-admin; ReferenceArrayInput labelTags referencetags sourcetags CheckboxGroupInput / /ReferenceArrayInput更多细节参见 ReferenceArrayInput 文档。源码级补充渲染结构与值处理原理为了让读者更深入理解组件的实际行为以下补充几个源码层面的关键实现均可直接在仓库中核对1. 组件的整体渲染结构CheckboxGroupInput.tsx组件渲染为 Material UI 的FormControlcomponentfieldset结构FormLabelcomponentlegend承载字段标题与必填星号FormGrouprow由 prop 控制内逐个渲染CheckboxGroupInputItemFormHelperText统一展示校验错误、拉取错误fetchError与自定义helperText。2. 选择状态的值解析CheckboxGroupInput.tsxhandleCheck在勾选/取消时维护数组值勾选时追加[...(value || []), newValue]取消时用宽松相等!过滤。关键细节是数字类型的自动转换如果所有选项的optionValue取值都是 number则会把复选框的字符串 value 通过JSON.parse转回数字——这保证了「值类型与候选 id 类型保持一致」测试用例分别验证了全字符串 id 不转换、数字 id 自动转回数字的两种提交结果见 CheckboxGroupInput.spec.tsx。3. 勾选状态的判定CheckboxGroupInputItem.tsx每个复选框的checked通过value.find(v v getChoiceValue(choice))判定同样使用宽松相等天然兼容字符串与数字的混合比较复选框的value统一为String(getChoiceValue(choice))这也是为什么上面需要数字转换逻辑来还原类型。4. 加载中状态CheckboxGroupInput.tsx当选项正在从引用资源拉取isPending为 true时组件渲染为Labeled包裹的LinearProgress进度条测试用例验证了未超过 1 秒不渲染、超过 1 秒且选项为空时出现进度条的行为见 CheckboxGroupInput.spec.tsx。5. 必填校验与焦点管理组件基于useInput接入表单状态支持validate校验Storybook 中Validate场景演示了配合required()使用首个复选框项通过inputRef参与表单焦点管理见 CheckboxGroupInput.tsx因此react-hook-form的setFocus同样可作用于该输入。总结CheckboxGroupInput用最简单直观的交互解决了「从有限候选集中多选」的需求。实际选型时可以遵循以下原则候选集较小、希望全部可见 →CheckboxGroupInput候选集较大或需要搜索 →SelectArrayInput/AutocompleteArrayInput选项来自其他资源 → 用ReferenceArrayInput包裹让父组件注入choices需要控制标签/值的字段名 →optionText/optionValue需要禁用部分选项 →disabled字段或自定义disableValue需要翻译选项 → 默认开启特殊场景用translateChoice{false}关闭。所有行为都有对应的源码与测试可查证组件实现位于 packages/ra-ui-materialui/src/input/CheckboxGroupInput.tsx 与 CheckboxGroupInputItem.tsx选项处理逻辑位于 packages/ra-core/src/form/choices/useChoices.tsx测试覆盖见 CheckboxGroupInput.spec.tsx交互演示见 CheckboxGroupInput.stories.tsx。【免费下载链接】react-adminA frontend Framework for single-page applications on top of REST/GraphQL APIs, using TypeScript, React and Material Design项目地址: https://gitcode.com/gh_mirrors/re/react-admin创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考