- 前端
- UI组件
【免费下载链接】rsuite
🧱 A suite of React components .
SelectPicker 是 rsuite 中用于单选数据选择的组件,默认自带一个搜索输入框,方便用户在大量选项中快速定位目标项。本文围绕 searchable 示例片段 展开,深入讲解searchable属性的两种用法、默认搜索匹配算法(useSearch与shouldDisplay)的源码实现,以及通过searchBy、onSearch实现自定义搜索与异步搜索的实战方案。读完本文,你将能精准控制 SelectPicker 的搜索开关,并根据业务场景定制匹配规则。
一、快速上手:用 searchable 控制搜索框
SelectPicker 的searchable属性用于控制是否渲染搜索输入框,默认值为true。当选项列表是固定的少量数据(例如性别、状态枚举等),或你希望用户只能从预设项中选择时,可以关闭搜索:
import { SelectPicker } from 'rsuite'; const data = ['Eugenia', 'Bryan', 'Linda', 'Nancy', 'Lloyd', 'Alice', 'Julia', 'Albert'].map( item => ({ label: item, value: item }) ); const App = () => ( <> {/* 关闭搜索,仅允许从预设选项中点选 */} <SelectPicker data={data} searchable={false} w={224} /> </> ); ReactDOM.render(<App />, document.getElementById('root'));其中w={224}是文档示例中用于设置组件宽度的简写形式(对应 style 宽度 224px)。开启搜索时(默认行为),点击组件展开弹层,顶部会出现一个搜索输入框,键入关键词后选项列表会即时过滤;关闭后弹层直接显示完整选项列表,不再出现搜索输入框。
该片段在组件文档中对应 "Disable Search" 一节,完整属性说明见 SelectPicker 文档。
二、源码视角:searchable 如何生效
从 SelectPicker 实现 可以看到,searchable的默认值为true(第 129 行),并且只在弹层渲染阶段决定是否挂载搜索框:
// src/SelectPicker/SelectPicker.tsx(片段) const renderPopup = (positionProps, speakerRef) => { // ... return ( <PickerPopup ...> {searchable && ( <SearchBox placeholder={locale?.searchPlaceholder} onChange={handleSearch} value={searchKeyword} inputRef={searchInput} /> )} {renderListbox ? renderListbox(listbox) : listbox} {renderExtraFooter?.()} </PickerPopup> ); };关键点:
searchable={false}时,整个SearchBox分支不会渲染,弹层内只剩选项列表(或自定义 footer),因此没有任何搜索入口;- 搜索框的占位文案来自
locale.searchPlaceholder,可通过CustomProvider的 locale 配置(Picker 系列共用)修改; - 搜索输入由
handleSearch驱动,内部维护searchKeyword状态,关闭弹层时(handleExit)会调用resetSearch()清空关键词,保证下次打开是干净列表(见 SelectPicker.tsx 第 246-251 行)。
三、默认搜索算法:useSearch 与 shouldDisplay
当searchable开启时,过滤逻辑由useSearchhook 完成,实现在 src/internals/Picker/hooks/useSearch.ts。该 hook 对外暴露searchKeyword、filteredData、handleSearch、resetSearch等结果:
// useSearch 核心流程 const filteredData = useMemo(() => { return data.filter(item => checkShouldDisplay(item, searchKeyword)); }, [checkShouldDisplay, data, searchKeyword]); const checkShouldDisplay = (item, keyword) => { const checkValue = typeof item === 'object' ? item?.[labelKey] : String(item); if (typeof searchBy === 'function') { return searchBy(keyword, checkValue, item); // 自定义规则优先 } return shouldDisplay(checkValue, keyword); // 默认匹配规则 };默认匹配规则shouldDisplay定义在 src/internals/Picker/utils.ts 第 32-44 行,其行为可以概括为:
- 大小写不敏感的子串匹配:关键词与 label 都会先经
toLocaleLowerCase()归一化,再通过indexOf判断是否包含; - 支持多种 label 形态:label 为字符串或数字时直接比较;label 为 React 元素(如自定义渲染的图标 + 文本)时,会先通过
reactToString提取文本内容再匹配; - 空关键词放行:
trim(searchKeyword)为空时直接返回true,即初始状态显示全部选项。
对应地,useSearch 单元测试 覆盖了默认关键词为空、初始返回全量数据、按对象labelKey过滤、自定义searchBy优先级、callback触发以及resetSearch重置等场景,可作为理解行为边界的参考。
四、自定义搜索:searchBy 精准控制匹配逻辑
当默认的包含匹配不满足需求(例如需要忽略某些字符、按拼音/首字母匹配、匹配 value 而非 label)时,可通过searchBy传入自定义判定函数:
// searchBy 签名:(keyword: string, label: ReactNode, item: Option) => boolean const searchBy = (keyword, label, item) => { // 示例:同时按 label 与 value 匹配 return `${label}${item.value}` .toLocaleLowerCase() .includes(keyword.toLocaleLowerCase()); }; <SelectPicker data={data} searchable searchBy={searchBy} />;从 useSearch 实现 可见,searchBy的优先级高于默认规则:只要传入searchBy函数,checkShouldDisplay就会直接调用它并以其返回值为准。这在自定义渲染(renderOption)返回复杂 ReactNode 的场景下尤其有用——shouldDisplay对 React 元素只能提取文本,而searchBy可以访问完整item数据。
五、onSearch 回调与异步搜索
onSearch在每次关键词变化时触发,签名与行为见 SelectPicker 文档:
onSearch?: (searchKeyword: string, event?: React.SyntheticEvent) => void;它最常见的用途是驱动异步数据加载:在onSearch中根据关键词请求远程接口,再更新data即可实现服务端搜索。文档中的 async 示例 展示了类似思路——通过onSearch/onOpen触发setTimeout延迟加载数据,并结合renderListbox在数据未就绪时渲染 Loader 占位。当弹层关闭时,组件会调用onSearch?.('')并清空过滤结果(见 SelectPicker.tsx 第 246-251 行),因此异步搜索需自行处理关键词为空时的兜底数据。
六、相关属性速查
以下是控制搜索行为及数据匹配的核心属性(取自 SelectPicker 属性表):
| 属性 | 类型(默认值) | 说明 |
|---|---|---|
searchable | boolean(true) | 是否显示搜索输入框,false时完全禁用搜索 |
searchBy | (keyword, label, item) => boolean | 自定义搜索判定函数,优先级高于默认包含匹配 |
onSearch | (searchKeyword, event) => void | 搜索关键词变化时触发,常用于异步加载 |
data | Option[](必填) | 选项数据源 |
labelKey | string('label') | 参与匹配的 label 字段名 |
valueKey | string('value') | 选项值字段名 |
groupBy | string | 分组字段,分组后搜索同样作用于各组内选项 |
小结
- 需要强制用户从预设项中选择时,设置
searchable={false}即可彻底关闭搜索入口; - 默认搜索是大小写不敏感的子串匹配,覆盖字符串、数字与 React 元素 label;
- 复杂匹配场景优先使用
searchBy自定义判定函数,可访问完整选项数据; - 需要远程搜索时,利用
onSearch回调触发数据加载,配合renderListbox展示加载态。
- 前端
- UI组件
【免费下载链接】rsuite
🧱 A suite of React components .
相关推荐
rsuite CheckTree 搜索能力完全指南:从 searchable 到自定义搜索规则
rsuite CheckTree 搜索能力完全指南:从 searchable 到自定义搜索规则 CheckTree 是 rsuite 中用于在树形结构中选择多个
前端UI组件rsuite MultiCascadeTree 搜索功能实战:从 searchable 属性到源码级搜索机制
rsuite MultiCascadeTree 搜索功能实战:从 searchable 属性到源码级搜索机制 MultiCascadeTree 是 rsuite
前端UI组件rsuite CheckPicker 搜索功能深度解析:searchable 开关、搜索机制与自定义过滤实战
rsuite CheckPicker 搜索功能深度解析:searchable 开关、搜索机制与自定义过滤实战 CheckPicker 是 rsuite 中用于多
前端UI组件
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考