
如何用 useAutoComplete 在 Refine Material UI 中实现远程搜索选择【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refine在 Refine 的 Material UI 集成包refinedev/mui中当某个资源例如categories的记录需要作为下拉选项、且输入框内容要触发对后端的搜索请求时可以用useAutocompletehook 管理 Material UI 的Autocomplete组件。它内部基于useListhook 取数通过 dataProvider 的getList方法把filters、pagination、sorters等参数发给 API因此“输入即搜索”的远程过滤能力来自onSearch属性而不是前端对已加载数据的本地过滤。本文以categories资源为例给出从基础接入到远程搜索、再到与表单结合的完整路径。准备条件一个已接入 Refine 的 React 应用安装了refinedev/mui并在Refine/中配置了dataProvideruseAutocomplete依赖其中的getList方法取数目标资源已在应用中可用本文示例统一使用resource: categories其记录形如interface ICategory { id: number; title: string; }第一步接入 useAutocomplete 获取基础选项最小用法是传入resource然后把返回的autocompleteProps整体展开到Autocomplete上import { useAutocomplete } from refinedev/mui; import { Autocomplete, TextField } from mui/material; interface ICategory { id: number; title: string; } const PostCreate: React.FC () { const { autocompleteProps } useAutocompleteICategory({ resource: categories, }); return ( Autocomplete {...autocompleteProps} getOptionLabel{(item) item.title} isOptionEqualToValue{(option, value) value undefined || option?.id?.toString() (value?.id ?? value)?.toString() } placeholderSelect a category renderInput{(params) ( TextField {...params} labelCategory marginnormal variantoutlined required / )} / ); };autocompleteProps中包含options、loading、onInputChange、filterOptions四个属性直接展开即可。完整可运行项目可参考仓库中的 field-material-ui-use-autocomplete 示例hook 的实现见 useAutocomplete 源码。第二步用 onSearch 实现远程搜索这是标题任务的核心。给useAutocomplete传一个onSearch回调它接收输入框的文本值返回一组CrudFilters结构的过滤条件条件会经useList传给dataProvider的getList由后端执行过滤const { autocompleteProps } useAutocompleteICategory({ resource: categories, onSearch: (value) [ { field: title, operator: contains, value, }, ], });两点需要注意onSearch一旦被使用会覆盖已有的filters属性两者不要同时依赖输入过程会频繁触发请求可配合debounce属性做防抖单位毫秒useAutocomplete({ resource: categories, onSearch: (value) [ { field: title, operator: contains, value }, ], debounce: 500, });从源码可以看到触发机制autocompleteProps.onInputChange在输入事件类型为change时调用onSearch(value)类型为click展开下拉时调用onSearch()。因此输入会带搜索词重新请求点击展开则按空搜索词重新拉取。可选分支改为客户端过滤如果数据量不大、不希望每次输入都请求后端可以把onSearch显式传为undefined禁用服务端过滤改用 Material UI 的createFilterOptions在本地过滤import { createFilterOptions } from mui/material; const { autocompleteProps } useAutocomplete({ resource: categories, }); const filterOptions createFilterOptions({ matchFrom: start, stringify: (option: any) option.title, }); Autocomplete {...autocompleteProps} getOptionLabel{(item) item.title} onInputChange{(event, value) {}} filterOptions{filterOptions} // 其余 props 同基础用法 /这是文档明确给出的替代路径远程搜索与客户端过滤二选一不要混在同一条操作链里。与 useForm / CRUD 组件结合在编辑已有记录时表单里保存的往往是{ id: ... }对象。useAutocomplete支持与useFormreact-hook-form结合通过Controller把选中值写回表单字段import { Create, useAutocomplete } from refinedev/mui; import { Box, Autocomplete, TextField } from mui/material; import { useForm } from refinedev/react-hook-form; import { Controller } from react-hook-form; const PostCreate: React.FC () { const { saveButtonProps, refineCore: { formLoading, query }, register, control, formState: { errors }, } useFormIPost, HttpError, IPost { category: ICategory }(); const { autocompleteProps } useAutocompleteICategory({ resource: categories, }); return ( Create isLoading{formLoading} saveButtonProps{saveButtonProps} Box componentform Controller control{control} namecategory rules{{ required: This field is required }} render{({ field }) ( Autocomplete {...autocompleteProps} {...field} onChange{(_, value) { field.onChange(value); }} getOptionLabel{({ title }) title} isOptionEqualToValue{(option, value) value undefined || option?.id?.toString() (value?.id ?? value)?.toString() } placeholderSelect a category renderInput{(params) ( TextField {...params} labelCategory marginnormal variantoutlined error{!!errors.category} helperText{errors.category?.message} required / )} / )} / /Box /Create ); };useAutocomplete也可以完全独立于useForm使用上例只是文档给出的组合方式。defaultValue保证只有 id 时也能显示选中项编辑页面经常只拿到id而该记录可能不在当前分页拉到的选项里Autocomplete会因此显示异常。传defaultValue后hook 会额外发起一次useMany查询把该记录取回来并并入optionsuseAutocomplete({ resource: categories, defaultValue: 1, // 或 [1, 2] });注意defaultValue不会设置默认选中它只保证该值存在于选项列表中。要设置默认选中应通过useForm的defaultValues或Autocomplete的value传入const form useForm({ defaultValues: { category: { id: 1 }, // 默认选中值 }, }); const { autocompleteProps } useAutocomplete({ resource: categories, defaultValue: [1], // 确保默认值出现在选项中 });若希望已选记录显示在选项列表顶部而非底部可用selectedOptionsOrder: selected-first默认in-place排在底部。验证是否生效选项是否来自后端autocompleteProps.loading为query.isFetching || defaultValueQuery.query.isFetching请求发出到返回期间为true说明数据确实经由getList拉取搜索是否走远程输入文本时观察网络请求getList请求应携带onSearch返回的过滤条件如title contains ...点击展开下拉时请求以空搜索词发起搜索不生效时的排查入口文档明确指出默认行为是用useList取数并把搜索条件作为参数发出若结果不对应检查自己 dataProvider 中getList函数如何处理filters参数——filters、sorters、pagination都只是被透传给getList后端不识别这些参数时过滤不会生效。其他常用参数均直接透传给getList或作为查询选项sorters控制选项排序如{ field: title, order: asc }pagination支持currentPage、pageSize和modeoff/client/serverqueryOptions透传给底层useQuery如{ retry: 3 }meta可向 dataProvider 方法传额外信息如自定义请求头多 dataProvider 场景用dataProviderName指定。更多细节见文档 useAutocomplete其中还包含实时更新liveMode、onLiveEvent需要配置LiveProvider与successNotification/errorNotification需要NotificationProvider等可选能力。【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refine创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考