Skip to content

refactor(Select): simplify option handling#9648

Open
zzjiaxiang wants to merge 15 commits into
ant-design:masterfrom
zzjiaxiang:select
Open

refactor(Select): simplify option handling#9648
zzjiaxiang wants to merge 15 commits into
ant-design:masterfrom
zzjiaxiang:select

Conversation

@zzjiaxiang

@zzjiaxiang zzjiaxiang commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

Summary by CodeRabbit

发布说明

  • Refactor

    • 重构 Select/SearchSelect:简化远程搜索数据流,SearchSelect 现在接收必填的 options,移除 defaultSearchValue;优化在请求/showSearch 场景下的搜索、清空、聚焦与重置联动,并支持将 request 透传到搜索逻辑。
    • 调整 Select 的选项来源与枚举映射,去除多余的关键词过滤/受控同步逻辑。
  • Bug Fixes

    • 收紧选项 value 类型,仅支持字符串或数字。
  • Tests

    • 更新并补充 ProFormSelect/SearchSelect 的 showSearchfetchDataOnSearch、分组过滤、清空等交互测试。

…nality

Removed unused filtering functions and optimized the options retrieval logic in the Select component. Updated the SearchSelect component to support enhanced search capabilities with a more flexible showSearch configuration. Adjusted typing for RequestOptionsType to remove boolean from value type. Updated tests to reflect changes in search handling.
…ct component

Introduced a new function for options mapping in the Select component, enhancing clarity and performance. Removed unused references and props in the SearchSelect component to simplify its implementation. Adjusted the handling of search functionality for improved user experience.
…earchSelect component

Refactored the FieldSelectSearchEdit component to directly use the defaultKeyWords prop for the default search value. Cleaned up the SearchSelect component by removing unnecessary comments and optimizing the focus handling logic.
…n handling

Updated the SearchSelect component to improve the handling of search functionality by allowing more flexible user configurations. Introduced destructuring for userConfig to streamline optionFilterProp, onSearch, and searchValue management. Added console logging for options to aid in debugging.
Eliminated the console logging of options in the SearchSelect component to enhance code cleanliness and maintainability.
Eliminated the optionFilterProp from the showSearch configuration in multiple instances of the ProForm component to streamline the search functionality and improve code clarity.
@dosubot dosubot Bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Jun 2, 2026
@coderabbitai

coderabbitai Bot commented Jun 2, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

重构 SearchSelect 的 showSearch 与 options 处理,简化 Select 的 options 源与过滤链路,收窄类型中 value 为仅允许 string|number,并同步调整相关测试与 FieldSelectSearchEdit 的默认关键词传递。

变更

Select与SearchSelect选项处理优化

Layer / File(s) 摘要
类型约束与值类型收窄
src/utils/typing.ts
RequestOptionsType.valueProSchemaValueEnumMap Map 键类型从 string | number | boolean 收窄为 string | number
SearchSelect 组件重写
src/field/components/Select/SearchSelect/index.tsx
更新导入与类型签名,SearchSelectProps.options 由可选改为必填;移除受控 searchValue、genOptions 与自定义 filterOption,直接透传 options 给 antd;ref 类型改为 GetRef<typeof Select> 并使用 useImperativeHandle 返回实例;通过 showSearch 对象注入包装后的 onSearch(在 fetchDataOnSearch 为 true 时先调用 fetchData),调整 onClear/onChange/onFocus 与 resetAfterSelect 行为。
Select 选项数据处理简化
src/field/components/Select/index.tsx
删除基于关键词的递归过滤函数 filerByItem,新增 getOptionsFormValueEnum 将 valueEnum 映射为 label/value 结构;useFieldFetchData 使用 useMemovalueEnumfieldProps.options 之间直接选择本地 options,存在 request 时直接返回 data ?? [],移除额外的 resOptions 构建与关键词过滤流程。
FieldSelectSearchEdit 与测试同步
src/field/components/Select/FieldSelectSearchEdit.tsx, tests/form/base.test.tsx
在 FieldSelectSearchEdit 中解构 defaultKeyWords 并传给 SearchSelect;测试中将原有直接传入的 onSearch 迁移到 showSearch: { onSearch },并根据新接口调整了若干用例(包含 fetchDataOnSearch、fieldNames 分组选项、allowClear、multiple + autoClearSearchValue 等)。

序列图

sequenceDiagram
  participant User as 用户
  participant SearchSelect as SearchSelect 组件
  participant FetchData as fetchData 函数
  participant OnSearch as showSearch.onSearch
  
  User->>SearchSelect: 输入搜索词
  alt fetchDataOnSearch 为 true
    SearchSelect->>FetchData: fetchData(value)
    FetchData-->>SearchSelect: 返回远程选项数据
  end
  SearchSelect->>OnSearch: 调用 showSearch.onSearch(value)
  
  User->>SearchSelect: 清空输入或触发 clear
  alt showSearch 存在 onSearch
    SearchSelect->>OnSearch: showSearch.onSearch('')
  else
    SearchSelect->>FetchData: fetchData(undefined)
  end
  
  User->>SearchSelect: 选择项目
  SearchSelect->>FetchData: resetData()
Loading

代码审查工作量估计

🎯 4 (Complex) | ⏱️ ~45 分钟

诗歌

🐰 重构的故事,简与繁的选择,
showSearch 对象配置,fetchData 联动舞蹈,
options 不再内转,选项来源更清晰,
boolean 退场了,string 与 number 独舞,
测试随之而改,一切如预期。

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR标题准确反映了主要变更内容,即简化Select组件的选项处理逻辑,涵盖了跨多个文件的核心重构。
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors the SearchSelect and FieldSelect components to simplify their implementation, removing custom filtering and value-merging logic in favor of delegating to the underlying Ant Design Select component. It also updates typing definitions to restrict option values to strings or numbers and adapts the test suite accordingly. The code review identifies critical issues introduced by this refactoring: removing the searchValue state locks the search input and prevents user interaction, and removing autoClearSearchValue breaks backward compatibility. The reviewer provides suggestions to restore an internal search value state, maintain backward compatibility, and optimize event handlers to prevent duplicate network requests.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines 91 to 107
const {
mode,
onSearch,
onFocus,
onChange,
autoClearSearchValue = true,
searchOnFocus = false,
resetAfterSelect = false,
fetchDataOnSearch = true,
optionFilterProp = 'label',
optionLabelProp = 'label',
className,
disabled,
options,
fetchData,
resetData,
prefixCls: customizePrefixCls,
onClear,
searchValue: propsSearchValue,
showSearch,
fieldNames,
showSearch: _showSearch,
defaultSearchValue,
...restProps
} = props;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

By removing the searchValue state, the search input becomes a controlled component locked to the initial defaultSearchValue when it is provided, preventing users from typing or changing the search query.

Additionally, autoClearSearchValue was removed from destructuring, which breaks backward compatibility for top-level autoClearSearchValue configurations.

This suggestion restores the innerSearchValue state and destructures autoClearSearchValue with a default of true to ensure full backward compatibility and correct behavior.

Suggested change
const {
mode,
onSearch,
onFocus,
onChange,
autoClearSearchValue = true,
searchOnFocus = false,
resetAfterSelect = false,
fetchDataOnSearch = true,
optionFilterProp = 'label',
optionLabelProp = 'label',
className,
disabled,
options,
fetchData,
resetData,
prefixCls: customizePrefixCls,
onClear,
searchValue: propsSearchValue,
showSearch,
fieldNames,
showSearch: _showSearch,
defaultSearchValue,
...restProps
} = props;
const {
onFocus,
onChange,
searchOnFocus = false,
resetAfterSelect = false,
fetchDataOnSearch = true,
className,
disabled,
options,
fetchData,
resetData,
prefixCls: customizePrefixCls,
onClear,
showSearch: _showSearch,
defaultSearchValue,
autoClearSearchValue = true,
...restProps
} = props;
const [innerSearchValue, setInnerSearchValue] = React.useState(defaultSearchValue);

Comment thread src/field/components/Select/SearchSelect/index.tsx Outdated
Comment thread src/field/components/Select/SearchSelect/index.tsx
@zzjiaxiang zzjiaxiang marked this pull request as draft June 2, 2026 16:29

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
tests/form/base.test.tsx (1)

2010-2017: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

SearchSelect 测试中 onSearch 配置请统一到 showSearch.onSearch

该用例把 onSearch 直接放在 fieldProps 顶层,但 SearchSelect 内部是从 showSearch 对象里读取并包装 onSearch 回调用于搜索触发;顶层 onSearch 在该路径下不如 showSearch.onSearch 一致。建议与其它 onSearch 用例保持同一写法。

🔄 建议一致性修复
 fieldProps={{
   mode: 'multiple',
   searchOnFocus: true,
-  onSearch: (e) => onSearch(e),
+  showSearch: {
+    onSearch: (e) => onSearch(e),
+  },
 }}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/form/base.test.tsx` around lines 2010 - 2017, The test uses
ProFormSelect.SearchSelect with onSearch set directly on fieldProps, but
SearchSelect expects and wraps the callback from the showSearch object; update
the test to move the onSearch handler into fieldProps.showSearch.onSearch (i.e.,
create or reuse a showSearch object on fieldProps and place the onSearch
function there) so the SearchSelect reads and invokes the same handler path as
other tests; refer to ProFormSelect.SearchSelect, fieldProps, showSearch, and
onSearch when making the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/field/components/Select/index.tsx`:
- Around line 107-110: The computed options can be undefined when valueEnum,
fieldProps?.options and request are all absent; update the useMemo for options
(the variable computed with useMemo and getOptionsFormValueEnum) to default to
an empty array instead of undefined so it always matches the SelectOptionType
contract and the now-required SearchSelectProps.options; i.e., ensure the
fallback after evaluating valueEnum and fieldProps?.options returns [].

In `@src/field/components/Select/SearchSelect/index.tsx`:
- Around line 125-139: showSearch 的构建里把 defaultSearchValue 回填到
showSearch.searchValue 会把输入变为受控组件导致锁定,改为不要在 SearchSelect 的内部设置 searchValue;在创建
showSearch(变量 _showSearch / userConfig)时保留 optionFilterProp、onSearch(仍在 onSearch
中调用 fetchData(value) 和 userConfig.onSearch?.(value)),但移除或不赋值 searchValue:
searchValue ?? defaultSearchValue,使默认关键词的初始化留给上游的 defaultKeyWords -> keyWords
链路而不是在 showSearch(或函数 showSearch)内强制控制 input 值。

---

Outside diff comments:
In `@tests/form/base.test.tsx`:
- Around line 2010-2017: The test uses ProFormSelect.SearchSelect with onSearch
set directly on fieldProps, but SearchSelect expects and wraps the callback from
the showSearch object; update the test to move the onSearch handler into
fieldProps.showSearch.onSearch (i.e., create or reuse a showSearch object on
fieldProps and place the onSearch function there) so the SearchSelect reads and
invokes the same handler path as other tests; refer to
ProFormSelect.SearchSelect, fieldProps, showSearch, and onSearch when making the
change.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: aef6368c-703c-4c49-aa7d-08973a4e8a18

📥 Commits

Reviewing files that changed from the base of the PR and between 165b9c1 and 4868eb1.

📒 Files selected for processing (5)
  • src/field/components/Select/FieldSelectSearchEdit.tsx
  • src/field/components/Select/SearchSelect/index.tsx
  • src/field/components/Select/index.tsx
  • src/utils/typing.ts
  • tests/form/base.test.tsx

Comment thread src/field/components/Select/index.tsx
Comment thread src/field/components/Select/SearchSelect/index.tsx
Comment thread src/field/components/Select/SearchSelect/index.tsx
… reliability

Updated the options retrieval logic in the Select component to default to an empty array when no options are provided, enhancing the robustness of the component. Additionally, removed the defaultSearchValue from the SearchSelect component to streamline its configuration handling.
…ity and remove unused defaultSearchValue

Updated the FieldSelectSearchEdit component to rename the defaultKeyWords prop to _defaultKeyWords for improved clarity. Removed the unused defaultSearchValue from the SearchSelect component to streamline its implementation.
@zzjiaxiang

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 13, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Updated the FieldSelectSearchEdit and SearchSelect components to incorporate the request prop for improved data fetching capabilities. Enhanced the options retrieval logic in the Select component to ensure better handling of default keywords and parameters, streamlining the overall configuration process.
@chenshuai2144 chenshuai2144 marked this pull request as ready for review June 20, 2026 03:05
Copilot AI review requested due to automatic review settings June 20, 2026 03:05
@dosubot dosubot Bot added size:XL This PR changes 500-999 lines, ignoring generated files. and removed size:L This PR changes 100-499 lines, ignoring generated files. labels Jun 20, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors the Select/SearchSelect implementation to simplify option sourcing and search behavior, and tightens option value typing (string/number only) to improve consistency and maintainability across ProForm Select variants.

Changes:

  • Refactors SearchSelect to centralize search config via showSearch and simplify options handling.
  • Simplifies useFieldFetchData option derivation and request behavior, prioritizing request/valueEnum/fieldProps options.
  • Updates related tests and type definitions to match the new search/options API.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
tests/form/base.test.tsx Updates SearchSelect-related tests to use the new showSearch config structure and adjusts related props.
src/utils/typing.ts Tightens option/valueEnum key types to `string
src/field/components/Select/SearchSelect/index.tsx Refactors SearchSelect behavior: new showSearch config handling, onSearch wiring, and simplified options pass-through.
src/field/components/Select/index.tsx Refactors option derivation and request fetching logic in useFieldFetchData.
src/field/components/Select/FieldSelectSearchEdit.tsx Updates FieldSelectSearchEdit to align with the refactored SearchSelect props.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +140 to 153
<Select
ref={selectRef}
className={classString}
allowClear
autoClearSearchValue={autoClearSearchValue}
disabled={disabled}
mode={mode}
showSearch={showSearch}
searchValue={searchValue}
optionFilterProp={optionFilterProp}
optionLabelProp={optionLabelProp}
onClear={() => {
onClear?.();
fetchData(undefined);
if (showSearch) {
onSearch?.('');
setSearchValue('');
if (isObject(showSearch) && showSearch.onSearch) {
showSearch.onSearch('');
} else {
fetchData(undefined);
}
}}
{...restProps}

@zzjiaxiang zzjiaxiang Jun 20, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

恢复成 antd-select allowClear 默认值一致

Comment on lines 154 to +160
onChange={(value, optionList, ...rest) => {
// 将搜索框置空 和 antd 行为保持一致
if (showSearch && autoClearSearchValue) {
if (isObject(showSearch) && showSearch.autoClearSearchValue) {
fetchData(undefined);
onSearch?.('');
setSearchValue('');
} else if (showSearch && !autoClearSearchValue) {
// 当 autoClearSearchValue 为 false 时,保持搜索值不变
// 但是需要确保我们的状态与 Ant Design 的内部状态同步
// 在 multiple 模式下,Ant Design 可能会自动清除搜索值,我们需要重新设置它
if (mode === 'multiple') {
// 在 multiple 模式下,即使 autoClearSearchValue 为 false,
// Ant Design 仍可能会清除搜索值,这是正常行为
// 我们不需要做任何特殊处理,让 Ant Design 自然处理
}
}

if (!props.labelInValue) {
onChange?.(value, optionList, ...rest);
return;
}

if (mode !== 'multiple' && !Array.isArray(optionList)) {
// 单选情况且用户选择了选项
let dataItem = optionList && optionList['data-item'];

// 如果 dataItem 不存在,尝试从 options 中查找对应的原始数据
let foundDataItem = dataItem;
if (!foundDataItem && value && options) {
const optionValue = value[valuePropsName] ?? value.value;
const findDataItem = (opts: RequestOptionsType[]): any => {
for (const opt of opts) {
const optValue = opt[valuePropsName] ?? opt.value;
if (optValue === optionValue) {
return opt;
}
if (opt[optionsPropsName] || opt.options) {
const found = findDataItem(
opt[optionsPropsName] || opt.options || [],
);
if (found) return found;
}
}
return null;
};
foundDataItem = findDataItem(options);
}

// 如果value值为空则是清空时产生的回调,直接传值就可以了
if (!value || !foundDataItem) {
const originalLabel = getOriginalLabel(foundDataItem, value);
const changedValue = value
? {
...value,
label: originalLabel,
}
: value;
onChange?.(changedValue, optionList, ...rest);
} else {
// 确保使用 dataItem.label(原始字符串),避免使用 value.label(可能是 optionItemRender 渲染的组件)
const originalLabel = getOriginalLabel(foundDataItem, value);
onChange?.(
{
...value,
...foundDataItem,
label: originalLabel,
},
optionList,
...rest,
);
}
return;
showSearch.onSearch?.('');
}
// 合并值
const mergeValue = getMergeValue(value, optionList) as any;
onChange?.(mergeValue, optionList, ...rest);

// 将搜索结果置空,重新搜索
onChange?.(value, optionList, ...rest);
Comment on lines 35 to 40
/** 防抖动时间 默认10 单位ms */
debounceTime?: number;
/** 自定义搜索方法, 返回搜索结果的 Promise */
request?: (params: { query: string }) => Promise<DataValueType<T>[]>;
/** 指定组件中的值 */
value?: KeyLabel | KeyLabel[];
Comment thread src/field/components/Select/SearchSelect/index.tsx Outdated
zzjiaxiang and others added 5 commits June 20, 2026 13:48
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Added a mechanism to ensure that only the latest data request result is used, preventing outdated responses from overwriting new data. This enhancement improves the reliability of data fetching in the Select component.
Updated the ProSchemaValueEnumMap type definition to only accept string and number as keys, removing boolean for improved type safety and clarity.
Streamlined the search handling logic in the SearchSelect component by removing unnecessary fetchData calls and consolidating the onSearch invocation. This change enhances clarity and maintains consistent behavior with the search functionality.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL This PR changes 500-999 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants