Skip to content

Commit fa85621

Browse files
committed
perf: code optimization
1 parent cdff8c1 commit fa85621

File tree

2 files changed

+80
-84
lines changed

2 files changed

+80
-84
lines changed

examples/mutiple-with-maxCount.tsx

Lines changed: 43 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -2,61 +2,62 @@ import React, { useState } from 'react';
22
import TreeSelect from '../src';
33

44
export default () => {
5-
const [value, setValue] = useState<string[]>(['1']);
6-
const [checkValue, setCheckValue] = useState<string[]>(['1']);
5+
const [value, setValue] = useState<string[]>();
6+
const [checkValue, setCheckValue] = useState<string[]>();
77

88
const treeData = [
99
{
10-
key: '1',
11-
value: '1',
12-
title: '1',
10+
title: 'Parent 1',
11+
value: 'parent1',
1312
children: [
1413
{
15-
key: '1-1',
16-
value: '1-1',
17-
title: '1-1',
14+
title: 'Child 1-1',
15+
value: 'child1-1',
1816
},
1917
{
20-
key: '1-2',
21-
value: '1-2',
22-
title: '1-2',
23-
disabled: true,
18+
title: 'Child 1-2',
19+
value: 'child1-2',
2420
children: [
2521
{
26-
key: '1-2-1',
27-
value: '1-2-1',
28-
title: '1-2-1',
29-
disabled: true,
22+
title: 'Child 1-2-1',
23+
value: 'child1-2-1',
24+
children: [
25+
{
26+
title: 'child 1-2-1-1',
27+
value: 'child1-2-1-1',
28+
children: [
29+
{
30+
title: 'child 1-2-1-1-1',
31+
value: 'child1-2-1-1-1',
32+
},
33+
],
34+
},
35+
{
36+
title: 'child 1-2-1-2',
37+
value: 'child1-2-1-2',
38+
},
39+
{
40+
title: 'child 1-2-1-3',
41+
value: 'child1-2-1-3',
42+
},
43+
],
3044
},
3145
{
32-
key: '1-2-2',
33-
value: '1-2-2',
34-
title: '1-2-2',
46+
title: 'Child 1-2-2',
47+
value: 'child1-2-2',
48+
},
49+
{
50+
title: 'Child 1-2-3',
51+
value: 'child1-2-3',
52+
},
53+
{
54+
title: 'Child 1-2-4',
55+
value: 'child1-2-4',
3556
},
3657
],
3758
},
38-
{
39-
key: '1-3',
40-
value: '1-3',
41-
title: '1-3',
42-
},
4359
],
4460
},
45-
{
46-
key: '2',
47-
value: '2',
48-
title: '2',
49-
},
50-
{
51-
key: '3',
52-
value: '3',
53-
title: '3',
54-
},
55-
{
56-
key: '4',
57-
value: '4',
58-
title: '4',
59-
},
6061
];
6162

6263
const onChange = (val: string[]) => {
@@ -69,36 +70,18 @@ export default () => {
6970

7071
return (
7172
<>
72-
<h2>multiple with maxCount</h2>
73-
<TreeSelect
74-
style={{ width: 300 }}
75-
fieldNames={{ value: 'value', label: 'title' }}
76-
multiple
77-
maxCount={3}
78-
treeData={treeData}
79-
/>
80-
<h2>checkable with maxCount</h2>
73+
<h2>maxCount = 3</h2>
8174
<TreeSelect
8275
style={{ width: 300 }}
8376
treeCheckable
77+
multiple
8478
// showCheckedStrategy="SHOW_ALL"
8579
// showCheckedStrategy="SHOW_PARENT"
86-
maxCount={4}
80+
maxCount={3}
8781
treeData={treeData}
8882
onChange={onChange}
8983
value={value}
9084
/>
91-
<h2>checkable with maxCount and treeCheckStrictly</h2>
92-
<TreeSelect
93-
style={{ width: 300 }}
94-
multiple
95-
treeCheckable
96-
treeCheckStrictly
97-
maxCount={3}
98-
treeData={treeData}
99-
onChange={onCheckChange}
100-
value={checkValue}
101-
/>
10285
</>
10386
);
10487
};

src/OptionList.tsx

Lines changed: 37 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -178,32 +178,45 @@ const OptionList: React.ForwardRefRenderFunction<ReviseRefOptionListProps> = (_,
178178
const isLeaf = (entity.children || []).length === 0;
179179

180180
if (!isLeaf) {
181-
const getLeafCheckableCount = (children: DataEntity<DataNode>[]): number => {
182-
return children.reduce((count, current) => {
183-
const currentValue = current.node[fieldNames.value];
184-
const currentEntity = valueEntities.get(currentValue);
185-
const isCurrentLeaf = (currentEntity.children || []).length === 0;
186-
187-
if (isCurrentLeaf) {
188-
if (
189-
!current.node.disabled &&
190-
!current.node.disableCheckbox &&
191-
!checkedKeys.includes(currentValue)
192-
) {
193-
return count + 1;
181+
const visited = new Set<string>();
182+
const stack: DataEntity<DataNode>[] = [entity];
183+
let checkableCount = 0;
184+
185+
while (stack.length > 0) {
186+
const currentEntity = stack.pop();
187+
const currentValue = currentEntity.node[fieldNames.value];
188+
189+
if (visited.has(currentValue)) {
190+
continue;
191+
}
192+
visited.add(currentValue);
193+
194+
const isCurrentLeaf = (currentEntity.children || []).length === 0;
195+
const isDisabled =
196+
currentEntity.node.disabled ||
197+
currentEntity.node.disableCheckbox ||
198+
checkedKeys.includes(currentValue);
199+
200+
if (isCurrentLeaf) {
201+
if (!isDisabled) {
202+
checkableCount++;
203+
204+
// break early
205+
if (checkableCount > leftMaxCount) {
206+
disabledCache.set(value, true);
207+
break;
194208
}
195-
} else if (
196-
!current.node.disabled &&
197-
!current.node.disableCheckbox &&
198-
!checkedKeys.includes(currentValue)
199-
) {
200-
return count + getLeafCheckableCount(currentEntity.children);
201209
}
202-
return count;
203-
}, 0);
204-
};
205-
const checkableChildrenCount = getLeafCheckableCount(entity.children);
206-
disabledCache.set(value, checkableChildrenCount > leftMaxCount);
210+
continue;
211+
}
212+
213+
if (!isDisabled) {
214+
for (let i = currentEntity.children.length - 1; i >= 0; i--) {
215+
stack.push(currentEntity.children[i]);
216+
}
217+
}
218+
}
219+
disabledCache.set(value, checkableCount > leftMaxCount);
207220
} else {
208221
disabledCache.set(value, false);
209222
}

0 commit comments

Comments
 (0)