From e6822f78bf483c655c0dfd6d295cd74bad90d05a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BA=8C=E8=B4=A7=E6=9C=BA=E5=99=A8=E4=BA=BA?= Date: Thu, 21 Nov 2024 21:38:45 +0800 Subject: [PATCH 1/5] test: test driven --- tests/Select.loadData.spec.tsx | 57 ++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 tests/Select.loadData.spec.tsx diff --git a/tests/Select.loadData.spec.tsx b/tests/Select.loadData.spec.tsx new file mode 100644 index 00000000..e307fe62 --- /dev/null +++ b/tests/Select.loadData.spec.tsx @@ -0,0 +1,57 @@ +/* eslint-disable no-undef, react/no-multi-comp, no-console */ +import Tree, { TreeNode } from 'rc-tree'; +import React from 'react'; +import { render, fireEvent, act } from '@testing-library/react'; + +import TreeSelect, { SHOW_ALL, SHOW_CHILD, SHOW_PARENT, TreeNode as SelectNode } from '../src'; +import { selectNode } from './util'; + +describe('TreeSelect.loadData', () => { + it('keep sync', async () => { + let renderTimes = 0; + let calledLastId: number | null = null; + + const Demo = () => { + const [treeData, setTreeData] = React.useState([ + { + title: '0', + value: 0, + isLeaf: false, + }, + ]); + + renderTimes += 1; + const renderId = renderTimes; + + const loadData = async () => { + calledLastId = renderId; + setTreeData([ + ...treeData, + { + title: `${renderId}`, + value: renderId, + isLeaf: true, + }, + ]); + }; + + return ; + }; + + render(); + + console.log(document.body.innerHTML); + + fireEvent.click(document.querySelector('.rc-tree-select-tree-switcher_close')); + await act(async () => { + await Promise.resolve(); + }); + expect(calledLastId).toBe(renderTimes); + + fireEvent.click(document.querySelector('.rc-tree-select-tree-switcher_close')); + await act(async () => { + await Promise.resolve(); + }); + expect(calledLastId).toBe(renderTimes); + }); +}); From e230c2ddb24e70ce52b360e3b0ef828cf309d697 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BA=8C=E8=B4=A7=E6=9C=BA=E5=99=A8=E4=BA=BA?= Date: Thu, 21 Nov 2024 21:47:15 +0800 Subject: [PATCH 2/5] fix: cache of loading --- src/OptionList.tsx | 12 +++++++--- tests/Select.loadData.spec.tsx | 41 +++++++++++++--------------------- 2 files changed, 24 insertions(+), 29 deletions(-) diff --git a/src/OptionList.tsx b/src/OptionList.tsx index aaa9d0ee..04c0f27b 100644 --- a/src/OptionList.tsx +++ b/src/OptionList.tsx @@ -243,9 +243,15 @@ const OptionList: React.ForwardRefRenderFunction = (_, const loadDataFun = useMemo( () => (searchValue ? null : (loadData as any)), - [searchValue, treeExpandedKeys || expandedKeys], - ([preSearchValue], [nextSearchValue, nextExcludeSearchExpandedKeys]) => - preSearchValue !== nextSearchValue && !!(nextSearchValue || nextExcludeSearchExpandedKeys), + [loadData, searchValue, treeExpandedKeys || expandedKeys], + ( + [prevLoadData, preSearchValue], + [nextLoadData, nextSearchValue, nextExcludeSearchExpandedKeys], + ) => + // `loadData` changed + prevLoadData !== nextLoadData || + // `searchValue` changed and not in search mode + (preSearchValue !== nextSearchValue && !!(nextSearchValue || nextExcludeSearchExpandedKeys)), ); // ========================== Render ========================== diff --git a/tests/Select.loadData.spec.tsx b/tests/Select.loadData.spec.tsx index e307fe62..c938d95c 100644 --- a/tests/Select.loadData.spec.tsx +++ b/tests/Select.loadData.spec.tsx @@ -1,16 +1,11 @@ /* eslint-disable no-undef, react/no-multi-comp, no-console */ -import Tree, { TreeNode } from 'rc-tree'; import React from 'react'; import { render, fireEvent, act } from '@testing-library/react'; -import TreeSelect, { SHOW_ALL, SHOW_CHILD, SHOW_PARENT, TreeNode as SelectNode } from '../src'; -import { selectNode } from './util'; +import TreeSelect from '../src'; describe('TreeSelect.loadData', () => { it('keep sync', async () => { - let renderTimes = 0; - let calledLastId: number | null = null; - const Demo = () => { const [treeData, setTreeData] = React.useState([ { @@ -20,17 +15,15 @@ describe('TreeSelect.loadData', () => { }, ]); - renderTimes += 1; - const renderId = renderTimes; - const loadData = async () => { - calledLastId = renderId; + const nextId = treeData.length; + setTreeData([ ...treeData, { - title: `${renderId}`, - value: renderId, - isLeaf: true, + title: `${nextId}`, + value: nextId, + isLeaf: false, }, ]); }; @@ -40,18 +33,14 @@ describe('TreeSelect.loadData', () => { render(); - console.log(document.body.innerHTML); - - fireEvent.click(document.querySelector('.rc-tree-select-tree-switcher_close')); - await act(async () => { - await Promise.resolve(); - }); - expect(calledLastId).toBe(renderTimes); - - fireEvent.click(document.querySelector('.rc-tree-select-tree-switcher_close')); - await act(async () => { - await Promise.resolve(); - }); - expect(calledLastId).toBe(renderTimes); + for (let i = 0; i < 5; i += 1) { + fireEvent.click(document.querySelector('.rc-tree-select-tree-switcher_close')); + await act(async () => { + await Promise.resolve(); + }); + expect( + document.querySelectorAll('.rc-tree-select-tree-list .rc-tree-select-tree-treenode'), + ).toHaveLength(2 + i); + } }); }); From 6b767b18f1c4d27add211f84763e85ae3096160b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BA=8C=E8=B4=A7=E6=9C=BA=E5=99=A8=E4=BA=BA?= Date: Thu, 21 Nov 2024 21:50:23 +0800 Subject: [PATCH 3/5] fix: off topic --- src/OptionList.tsx | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/OptionList.tsx b/src/OptionList.tsx index 04c0f27b..d21cf5cb 100644 --- a/src/OptionList.tsx +++ b/src/OptionList.tsx @@ -10,6 +10,7 @@ import LegacyContext from './LegacyContext'; import TreeSelectContext from './TreeSelectContext'; import type { Key, SafeKey } from './interface'; import { getAllKeys, isCheckDisabled } from './utils/valueUtil'; +import { useEvent } from 'rc-util'; const HIDDEN_STYLE = { width: 0, @@ -241,17 +242,13 @@ const OptionList: React.ForwardRefRenderFunction = (_, onKeyUp: () => {}, })); + const syncLoadData = useEvent(loadData); + const loadDataFun = useMemo( - () => (searchValue ? null : (loadData as any)), - [loadData, searchValue, treeExpandedKeys || expandedKeys], - ( - [prevLoadData, preSearchValue], - [nextLoadData, nextSearchValue, nextExcludeSearchExpandedKeys], - ) => - // `loadData` changed - prevLoadData !== nextLoadData || - // `searchValue` changed and not in search mode - (preSearchValue !== nextSearchValue && !!(nextSearchValue || nextExcludeSearchExpandedKeys)), + () => (searchValue ? null : (syncLoadData as any)), + [searchValue, treeExpandedKeys || expandedKeys], + ([preSearchValue], [nextSearchValue, nextExcludeSearchExpandedKeys]) => + preSearchValue !== nextSearchValue && !!(nextSearchValue || nextExcludeSearchExpandedKeys), ); // ========================== Render ========================== From 46663471b152ada9f51adac676fc2144584083c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BA=8C=E8=B4=A7=E6=9C=BA=E5=99=A8=E4=BA=BA?= Date: Thu, 21 Nov 2024 22:07:48 +0800 Subject: [PATCH 4/5] fix: sync load logic --- src/OptionList.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/OptionList.tsx b/src/OptionList.tsx index d21cf5cb..d8ff001f 100644 --- a/src/OptionList.tsx +++ b/src/OptionList.tsx @@ -242,15 +242,15 @@ const OptionList: React.ForwardRefRenderFunction = (_, onKeyUp: () => {}, })); - const syncLoadData = useEvent(loadData); - - const loadDataFun = useMemo( - () => (searchValue ? null : (syncLoadData as any)), + const hasLoadDataFn = useMemo( + () => (searchValue ? false : true), [searchValue, treeExpandedKeys || expandedKeys], ([preSearchValue], [nextSearchValue, nextExcludeSearchExpandedKeys]) => preSearchValue !== nextSearchValue && !!(nextSearchValue || nextExcludeSearchExpandedKeys), ); + const syncLoadData = hasLoadDataFn ? loadData : null; + // ========================== Render ========================== if (memoTreeData.length === 0) { return ( @@ -292,7 +292,7 @@ const OptionList: React.ForwardRefRenderFunction = (_, showIcon={showTreeIcon} switcherIcon={switcherIcon} showLine={treeLine} - loadData={loadDataFun} + loadData={syncLoadData} motion={treeMotion} activeKey={activeKey} // We handle keys by out instead tree self From 70361d4d0d274776ef07dbac6ed918cc35bc0b35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BA=8C=E8=B4=A7=E6=9C=BA=E5=99=A8=E4=BA=BA?= Date: Thu, 21 Nov 2024 22:08:51 +0800 Subject: [PATCH 5/5] chore: fix lint --- src/OptionList.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/OptionList.tsx b/src/OptionList.tsx index d8ff001f..bbfa37f9 100644 --- a/src/OptionList.tsx +++ b/src/OptionList.tsx @@ -10,7 +10,6 @@ import LegacyContext from './LegacyContext'; import TreeSelectContext from './TreeSelectContext'; import type { Key, SafeKey } from './interface'; import { getAllKeys, isCheckDisabled } from './utils/valueUtil'; -import { useEvent } from 'rc-util'; const HIDDEN_STYLE = { width: 0,