From bb13fc8fa2445546fce165aa0ef9313514d7330f Mon Sep 17 00:00:00 2001 From: DuQi Date: Sat, 6 Jun 2026 12:48:45 +0800 Subject: [PATCH 1/2] fix: restore load switcher after clearing search --- src/OptionList.tsx | 20 ++++++++++++++++---- tests/Select.loadData.spec.tsx | 24 ++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/src/OptionList.tsx b/src/OptionList.tsx index b1efdac5..bd238c21 100644 --- a/src/OptionList.tsx +++ b/src/OptionList.tsx @@ -138,8 +138,21 @@ const OptionList: React.ForwardRefRenderFunction = (_, if (treeExpandedKeys) { return [...treeExpandedKeys]; } - return searchValue ? searchExpandedKeys : expandedKeys; - }, [expandedKeys, searchExpandedKeys, treeExpandedKeys, searchValue]); + if (searchValue) { + return searchExpandedKeys; + } + if (searchExpandedKeys && loadData && !treeDefaultExpandAll) { + return expandedKeys || []; + } + return expandedKeys; + }, [ + expandedKeys, + searchExpandedKeys, + treeExpandedKeys, + searchValue, + loadData, + treeDefaultExpandAll, + ]); const onInternalExpand = (keys: Key[]) => { setExpandedKeys(keys); @@ -315,8 +328,7 @@ const OptionList: React.ForwardRefRenderFunction = (_, () => (searchValue ? false : true), // eslint-disable-next-line react-hooks/exhaustive-deps [searchValue, treeExpandedKeys || expandedKeys], - ([preSearchValue], [nextSearchValue, nextExcludeSearchExpandedKeys]) => - preSearchValue !== nextSearchValue && !!(nextSearchValue || nextExcludeSearchExpandedKeys), + ([preSearchValue], [nextSearchValue]) => preSearchValue !== nextSearchValue, ); const syncLoadData = hasLoadDataFn ? loadData : null; diff --git a/tests/Select.loadData.spec.tsx b/tests/Select.loadData.spec.tsx index c938d95c..46f2b15b 100644 --- a/tests/Select.loadData.spec.tsx +++ b/tests/Select.loadData.spec.tsx @@ -43,4 +43,28 @@ describe('TreeSelect.loadData', () => { ).toHaveLength(2 + i); } }); + + it('keeps load switcher after clearing search value', () => { + const loadData = jest.fn(() => Promise.resolve()); + const { container } = render( + , + ); + + const input = container.querySelector('input')!; + + expect(container.querySelector('.rc-tree-select-tree-switcher_close')).toBeTruthy(); + + fireEvent.change(input, { target: { value: '1' } }); + fireEvent.change(input, { target: { value: '' } }); + + expect(loadData).not.toHaveBeenCalled(); + expect(container.querySelector('.rc-tree-select-tree-switcher_close')).toBeTruthy(); + expect(container.querySelector('.rc-tree-select-tree-switcher-noop')).toBeFalsy(); + }); }); From 06a5e3b5198e1ea8fdec9444130d6a2e3ef6e8b0 Mon Sep 17 00:00:00 2001 From: DuQi Date: Sat, 6 Jun 2026 13:12:08 +0800 Subject: [PATCH 2/2] test: cover load switcher after clearing search --- src/OptionList.tsx | 3 +-- tests/Select.loadData.spec.tsx | 9 ++++++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/OptionList.tsx b/src/OptionList.tsx index bd238c21..bfb03364 100644 --- a/src/OptionList.tsx +++ b/src/OptionList.tsx @@ -326,8 +326,7 @@ const OptionList: React.ForwardRefRenderFunction = (_, const hasLoadDataFn = useMemo( () => (searchValue ? false : true), - // eslint-disable-next-line react-hooks/exhaustive-deps - [searchValue, treeExpandedKeys || expandedKeys], + [searchValue], ([preSearchValue], [nextSearchValue]) => preSearchValue !== nextSearchValue, ); diff --git a/tests/Select.loadData.spec.tsx b/tests/Select.loadData.spec.tsx index 46f2b15b..6ed20007 100644 --- a/tests/Select.loadData.spec.tsx +++ b/tests/Select.loadData.spec.tsx @@ -44,7 +44,7 @@ describe('TreeSelect.loadData', () => { } }); - it('keeps load switcher after clearing search value', () => { + it('keeps load switcher after clearing search value', async () => { const loadData = jest.fn(() => Promise.resolve()); const { container } = render( { expect(loadData).not.toHaveBeenCalled(); expect(container.querySelector('.rc-tree-select-tree-switcher_close')).toBeTruthy(); expect(container.querySelector('.rc-tree-select-tree-switcher-noop')).toBeFalsy(); + + fireEvent.click(container.querySelector('.rc-tree-select-tree-switcher_close')!); + await act(async () => { + await Promise.resolve(); + }); + + expect(loadData).toHaveBeenCalledTimes(1); }); });