Refine v5 useCheckboxGroup Hook 实战指南:用 Ant Design Checkbox.Group 渲染资源选项
Refine v5 useCheckboxGroup Hook 实战指南用 Ant Design Checkbox.Group 渲染资源选项【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refineuseCheckboxGroup是 Refine v5 中面向 Ant Design 的字段类 Hook它把某个 resource 的列表记录自动转换成Checkbox.Group所需的options让你无需手写数据请求与选项映射即可在创建/编辑表单中渲染多选复选组。本文基于 documentation/docs/ui-integrations/ant-design/hooks/use-checkbox-group/index.md 展开并结合仓库内的源码、测试与可运行示例完整讲解全部配置项、返回值、类型参数及其底层实现原理读完可直接在项目里落地使用。useCheckboxGroup 是什么在 Refine v5 中useCheckboxGroup用于管理 Ant Design 的 Checkbox.Group 组件——当某个资源resource的记录需要被当作复选框选项时用它来获取数据并生成选项。它本质上是对 Refine 核心层useSelectHook 的封装。源码位于 packages/antd/src/hooks/fields/useCheckboxGroup/index.tsexport const useCheckboxGroup ({ resource, sorters, filters, optionLabel, optionValue, queryOptions, pagination, liveMode, defaultValue, selectedOptionsOrder, onLiveEvent, liveParams, meta, dataProviderName, ...rest }) { const { query, options } useSelect({ ... }); return { checkboxGroupProps: { options, defaultValue }, query, }; };可以看到useCheckboxGroup内部直接委托给refinedev/core的useSelect然后把产出的options和defaultValue组装成checkboxGroupProps返回调用方只需把它展开传给Checkbox.Group即可。而useSelect的数据获取又是基于useListHook 完成的——也就是说useCheckboxGroup的整个数据链路是useCheckboxGroup → useSelect → useList → dataProvider.getList。关于useList的完整能力排序、过滤、分页、实时更新等可参阅 documentation/docs/data/hooks/use-list/index.md。快速上手把资源记录渲染成复选框下面演示从https://api.fake-rest.refine.dev的/tags端点获取数据。该接口返回的记录形如// GET /tags 返回的数据 [ { id: 1, title: Driver Deposit, }, { id: 2, title: Index Compatible Synergistic, }, { id: 3, title: Plum, }, ];在创建页中只需要三行核心代码// pages/posts/create.tsx import { useCheckboxGroup } from refinedev/antd; import { Form, Checkbox } from antd; export const PostCreate: React.FC () { const { checkboxGroupProps } useCheckboxGroupITag({ resource: tags, }); return ( Form Form.Item labelTags nametags Checkbox.Group {...checkboxGroupProps} / /Form.Item /Form ); }; interface ITag { id: number; title: string; }我们唯一要做的事情就是把useCheckboxGroup返回的checkboxGroupProps展开传给Checkbox.Group。Hook 会根据每个记录的id生成value、根据title生成label自动得到如下所示的选项组每个 tag 对应一个复选框勾选后以Form的nametags字段提交。仓库中提供了该示例的完整可运行版本 examples/field-antd-use-checkbox-group其中 create.tsx 展示了在Create页面中与useForm组合的完整写法edit.tsx 展示了编辑页用法接口类型定义在 interfaces/index.d.tsexport interface ITag { id: number; title: string; } export interface IPost { id: number; title: string; content: string; tags: Arraystring; }Options 配置项详解resourceresource决定从哪个 API 资源端点拉取记录该值最终会传给dataProvider的getList方法const { checkboxGroupProps } useCheckboxGroup({ resource: tags, });它返回的是按复选框语义配置好的options值。如果存在多个同名资源可以传入identifier来替代资源的name。identifier只作为资源的主匹配键数据提供者的方法仍然会使用Refine/组件中定义的name来工作。关于identifier的语义可参阅 documentation/docs/core/refine-component/index.md 中的 identifier 一节。defaultValue通过defaultValue可以轻松地为复选框字段预设默认选中值const { selectProps } useCheckboxGroup({ resource: languages, defaultValue: [1, 2], });从 useSelect 源码 可以看到defaultValue会通过useMany以getMany方法额外发起一次查询把对应的记录转换成selectedOptions追加进最终选项列表const defaultValueQueryResult useMany({ resource: identifier ?? resource?.name ?? , ids: defaultValues, ... });这意味着即便默认值对应的记录不在当前列表页的数据里它们也会被正确拉取并展示为已选中状态。selectedOptionsOrderselectedOptionsOrder用于控制defaultValue对应的selectedOptions在选项列表中的排序位置取值有两种in-placeselectedOptions排在列表底部默认值selected-firstselectedOptions排在列表顶部const { selectProps } useCheckboxGroup({ resource: languages, defaultValue: [1, 2], selectedOptionsOrder: selected-first, // in-place | selected-first });在 useSelect 源码 中这一行为由uniqBy合并逻辑实现——in-place时先合并列表选项再拼上选中选项selected-first则相反最后按value去重const combinedOptions useMemo( () uniqBy( selectedOptionsOrder in-place ? [...options, ...selectedOptions] : [...selectedOptions, ...options], value, ), [options, selectedOptions], );对应的单元测试见 packages/core/src/hooks/useSelect/index.spec.ts它验证了selectedOptionsOrder: selected-first时选中项{ value: 2 }会排在最前。optionLabel 与 optionValueoptionLabel和optionValue允许你自定义选项的显示文本与值默认值分别为optionLabel title、optionValue idconst { checkboxGroupProps } useCheckboxGroup({ resource: tags, optionLabel: title, optionValue: id, });这两个属性都支持Object path 嵌套路径语法基于 lodashget适合记录中字段被嵌套的场景const { options } useCheckboxGroup({ resource: categories, optionLabel: nested.title, optionValue: nested.id, });也可以传入函数形式函数会接收到item参数适合拼接展示const { options } useCheckboxGroup({ optionLabel: (item) ${item.firstName} ${item.lastName}, optionValue: (item) item.id, });在 useSelect 源码 中可以看到实现字符串路径走get(item, optionLabel)函数则直接调用默认值optionLabel title、optionValue id也在此处定义optionLabel title, optionValue id,searchFieldsearchField用于指定onSearch函数搜索时匹配的字段const { onSearch } useCheckboxGroup({ searchField: name }); onSearch(John); // 用 name 字段、值为 John 进行搜索其默认取值规则为如果optionLabel是字符串则使用optionLabel的值否则回退到title字段// optionLabel 是字符串时 const { onSearch } useCheckboxGroup({ optionLabel: name }); onSearch(John); // 用 name 字段搜索 // optionLabel 是函数时 const { onSearch } useCheckboxGroup({ optionLabel: (item) ${item.id} - ${item.name}, }); onSearch(John); // 回退到 title 字段搜索源码中的默认值逻辑见 packages/core/src/hooks/useSelect/index.tssearchField typeof optionLabel string ? optionLabel : title,当调用onSearch时会生成一个operator: contains的过滤条件并合并进列表查询源码。同时该回调内置了防抖默认300ms可通过debounce属性调整。相关行为在 packages/core/src/hooks/useSelect/index.spec.ts 中有针对三种情形字符串optionLabel、函数optionLabel、显式searchField的参数化测试覆盖。filtersfilters允许在获取数据时附加过滤条件。例如只想列出title等于 Driver Deposit 的标签const { checkboxGroupProps } useCheckboxGroup({ resource: tags, filters: [ { field: title, operator: eq, value: Driver Deposit, }, ], });这些filters会透传给useList最终到达dataProvider.getList其完整类型定义与各操作符说明可参考 documentation/docs/core/interface-references/index.md 中的CrudFilters一节。sorterssorters允许对选项进行排序。例如按title升序排列const { checkboxGroupProps } useCheckboxGroup({ resource: tags, sorters: [ { field: title, order: asc, }, ], });在 examples/field-antd-use-checkbox-group/src/pages/posts/create.tsx 的完整示例中正是通过sorters让标签列表按标题升序展示const { checkboxGroupProps: tagsCheckboxGroupProps } useCheckboxGroupITag({ resource: tags, sorters: [ { field: title, order: asc, }, ], });fetchSizefetchSize表示复选框一次拉取的记录数量const { selectProps } useCheckboxGroup({ resource: languages, fetchSize: 20, });版本注意在较新的版本中fetchSize已被弃用见 packages/antd/CHANGELOG.md 中 useSelect()fetchSizeprop is deprecated 的记录官方建议改用下文介绍的pagination来精确控制每次拉取的条数。当前useSelect的类型定义中已不再包含fetchSize相关测试也仅保留在历史快照里。paginationpagination用于设置页码与每页条数。例如有 1000 条 post 记录希望从第 3 页开始、每页显示 8 条const { selectProps } useCheckboxGroup({ resource: categories, pagination: { currentPage: 3, pageSize: 8 }, });列表将从第 3 页开始每页展示 8 条记录。pagination支持currentPage、pageSize以及mode是否启用服务端分页默认off其类型定义见 packages/core/src/hooks/useSelect/index.ts。在 useList 内部 被转发时pageSize的默认值为10pagination: { currentPage: pagination?.currentPage, pageSize: pagination?.pageSize ?? 10, mode: pagination?.mode, },queryOptionsqueryOptions允许你透传 TanStack Query 的useQuery配置项例如自定义错误回调const { checkboxGroupProps } useCheckboxGroup({ resource: tags, queryOptions: { onError: () { console.log(triggers when on query return Error); }, }, });从 useSelect 类型定义 可以看到queryOptions接受MakeOptionalUseQueryOptionsGetListResponseTQueryFnData, TError, GetListResponseTData, queryKey | queryFn即除了queryKey和queryFn之外的完整useQuery选项如enabled、onSuccess、staleTime、retry等都可使用。返回值说明useCheckboxGroup的返回类型定义见 packages/antd/src/hooks/fields/useCheckboxGroup/index.tsexport type UseCheckboxGroupReturnTypeTData, TOption, TError { checkboxGroupProps: Omit React.ComponentPropstypeof Checkbox.Group, options { options: TOption[]; }; query: QueryObserverResultGetListResponseTData, TError; };checkboxGroupProps可直接展开传给Checkbox.Group的属性集合核心是options{ label, value }[]数组与defaultValuequeryTanStack Query 的查询结果对象QueryObserverResult可通过query.isLoading、query.isSuccess、query.data、query.refetch()等来感知加载状态、读取原始记录或手动刷新数据。与表单集成的完整模式把useCheckboxGroup放进Form.Item配合useForm就能获得完整的创建 编辑体验。创建页见 examples/field-antd-use-checkbox-group/src/pages/posts/create.tsximport { Create, useForm, useCheckboxGroup } from refinedev/antd; import { Form, Input, Checkbox } from antd; import MDEditor from uiw/react-md-editor; import type { IPost, ITag } from ../../interfaces; export const PostCreate () { const { formProps, saveButtonProps } useFormIPost(); const { checkboxGroupProps: tagsCheckboxGroupProps } useCheckboxGroupITag({ resource: tags, sorters: [{ field: title, order: asc }], }); return ( Create saveButtonProps{saveButtonProps} Form {...formProps} layoutvertical Form.Item labelTitle nametitle rules{[{ required: true }]} Input / /Form.Item Form.Item labelTag nametags rules{[{ required: true }]} Checkbox.Group {...tagsCheckboxGroupProps} / /Form.Item Form.Item labelContent namecontent rules{[{ required: true }]} MDEditor>type BaseRecord { id?: BaseKey; [key: string]: any; }; type HttpError { message: string; statusCode: number; errors?: ValidationErrors; [key: string]: any; };典型用法是像示例中那样useCheckboxGroupITag({ resource: tags })让 TypeScript 在optionLabel/optionValue及回调参数上提供字段提示与类型检查。小结useCheckboxGroup把拉取资源 → 映射选项 → 渲染 Checkbox.Group这条链路压缩成了一个 Hook 调用开箱即用默认以id/title生成选项支持identifier、filters、sorters、pagination等完整的列表控制能力灵活定制optionLabel/optionValue支持字符串路径与函数两种形式searchField可自定义搜索字段表单友好配合useForm与Form.Item创建/编辑页都能零成本集成defaultValue与selectedOptionsOrder保证已选选项的展示与回填。建议进一步阅读 useList 文档 以理解其背后的分页、过滤与实时能力并在 field-antd-use-checkbox-group 示例 中运行体验完整效果。【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refine创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考