diff --git a/components/cascader/__tests__/index.test.js b/components/cascader/__tests__/index.test.js
index 50ba05cf98..4d9bc17fff 100644
--- a/components/cascader/__tests__/index.test.js
+++ b/components/cascader/__tests__/index.test.js
@@ -524,4 +524,22 @@ describe('Cascader', () => {
wrapper.find('input').simulate('change', { target: { value: 'jin' } });
expect(wrapper.state('popupVisible')).toBe(true);
});
+
+ it('onChange works correctly when the label of fieldNames is the same as value', () => {
+ const onChange = jest.fn();
+ const sameNames = { label: 'label', value: 'label', children: 'children' };
+ const wrapper = mount(
+ ,
+ );
+ wrapper.find('input').simulate('click');
+ wrapper.find('input').simulate('change', { target: { value: 'est' } });
+ const popupWrapper = mount(wrapper.find('Cascader').find('Trigger').instance().getComponent());
+ popupWrapper
+ .find('.ant-cascader-menu')
+ .at(0)
+ .find('.ant-cascader-menu-item')
+ .at(0)
+ .simulate('click');
+ expect(onChange).toHaveBeenCalledWith(['Zhejiang', 'Hangzhou', 'West Lake'], expect.anything());
+ });
});
diff --git a/components/cascader/index.tsx b/components/cascader/index.tsx
index e698e0a0eb..c49036ad4c 100644
--- a/components/cascader/index.tsx
+++ b/components/cascader/index.tsx
@@ -128,6 +128,9 @@ interface CascaderLocale {
// We limit the filtered item count by default
const defaultLimit = 50;
+// keep value when filtering
+const keepFilteredValueField = '__KEEP_FILTERED_OPTION_VALUE';
+
function highlightKeyword(str: string, keyword: string, prefixCls: string | undefined) {
return str.split(keyword).map((node: string, index: number) =>
index === 0
@@ -308,7 +311,10 @@ class Cascader extends React.Component {
handleChange = (value: any, selectedOptions: CascaderOptionType[]) => {
this.setState({ inputValue: '' });
if (selectedOptions[0].__IS_FILTERED_OPTION) {
- const unwrappedValue = value[0];
+ const unwrappedValue =
+ selectedOptions[0][keepFilteredValueField] === undefined
+ ? value[0]
+ : selectedOptions[0][keepFilteredValueField];
const unwrappedSelectedOptions = selectedOptions[0].path;
this.setValue(unwrappedValue, unwrappedSelectedOptions);
return;
@@ -413,11 +419,14 @@ class Cascader extends React.Component {
filtered = filtered.sort((a, b) => sort(a, b, inputValue, names));
if (filtered.length > 0) {
+ // Fix issue: https://github.com/ant-design/ant-design/issues/26554
+ const field = names.value === names.label ? keepFilteredValueField : names.value;
+
return filtered.map((path: CascaderOptionType[]) => {
return {
__IS_FILTERED_OPTION: true,
path,
- [names.value]: path.map((o: CascaderOptionType) => o[names.value]),
+ [field]: path.map((o: CascaderOptionType) => o[names.value]),
[names.label]: render(inputValue, path, prefixCls, names),
disabled: path.some((o: CascaderOptionType) => !!o.disabled),
isEmptyNode: true,