Skip to content

Commit 92d47ce

Browse files
committed
refactor code
1 parent 02f25e5 commit 92d47ce

File tree

3 files changed

+45
-60
lines changed

3 files changed

+45
-60
lines changed

src/hooks/useFilterTreeData.ts

Lines changed: 17 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,18 @@ import * as React from 'react';
22
import type { DefaultOptionType, InternalFieldName, TreeSelectProps } from '../TreeSelect';
33
import { fillLegacyProps } from '../utils/legacyUtil';
44

5-
type GetFuncType<T> = T extends boolean ? never : T;
6-
type FilterFn = GetFuncType<TreeSelectProps['filterTreeNode']>;
5+
type FilterFn = NonNullable<TreeSelectProps['filterTreeNode']>;
76

8-
export default (
7+
const useFilterTreeData = (
98
treeData: DefaultOptionType[],
109
searchValue: string,
11-
{
12-
treeNodeFilterProp,
13-
filterTreeNode,
14-
fieldNames,
15-
}: {
10+
options: {
1611
fieldNames: InternalFieldName;
1712
treeNodeFilterProp: string;
1813
filterTreeNode: TreeSelectProps['filterTreeNode'];
1914
},
2015
) => {
16+
const { fieldNames, treeNodeFilterProp, filterTreeNode } = options;
2117
const { children: fieldChildren } = fieldNames;
2218

2319
return React.useMemo(() => {
@@ -31,24 +27,24 @@ export default (
3127
: (_, dataNode) =>
3228
String(dataNode[treeNodeFilterProp]).toUpperCase().includes(searchValue.toUpperCase());
3329

34-
function dig(list: DefaultOptionType[], keepAll: boolean = false) {
35-
return list.reduce<DefaultOptionType[]>((total, dataNode) => {
36-
const children = dataNode[fieldChildren];
30+
const filterTreeNodes = (nodes: DefaultOptionType[], keepAll = false): DefaultOptionType[] =>
31+
nodes.reduce<DefaultOptionType[]>((filtered, node) => {
32+
const children = node[fieldChildren];
33+
const isMatch = keepAll || filterOptionFunc(searchValue, fillLegacyProps(node));
34+
const filteredChildren = filterTreeNodes(children || [], isMatch);
3735

38-
const match = keepAll || filterOptionFunc(searchValue, fillLegacyProps(dataNode));
39-
const childList = dig(children || [], match);
40-
41-
if (match || childList.length) {
42-
total.push({
43-
...dataNode,
36+
if (isMatch || filteredChildren.length) {
37+
filtered.push({
38+
...node,
4439
isLeaf: undefined,
45-
[fieldChildren]: childList,
40+
[fieldChildren]: filteredChildren,
4641
});
4742
}
48-
return total;
43+
return filtered;
4944
}, []);
50-
}
5145

52-
return dig(treeData);
46+
return filterTreeNodes(treeData);
5347
}, [treeData, searchValue, fieldChildren, treeNodeFilterProp, filterTreeNode]);
5448
};
49+
50+
export default useFilterTreeData;

src/hooks/useTreeData.ts

Lines changed: 26 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -3,45 +3,35 @@ import type { DataNode, SimpleModeConfig } from '../interface';
33
import { convertChildrenToData } from '../utils/legacyUtil';
44
import type { DefaultOptionType } from '../TreeSelect';
55

6-
function parseSimpleTreeData(
7-
treeData: DataNode[],
8-
{ id, pId, rootPId }: SimpleModeConfig,
9-
): DataNode[] {
10-
const keyNodes = {};
11-
const rootNodeList = [];
12-
13-
// Fill in the map
14-
const nodeList = treeData.map(node => {
15-
const clone = { ...node };
16-
const key = clone[id];
17-
keyNodes[key] = clone;
18-
clone.key = clone.key || key;
19-
return clone;
6+
function buildTreeStructure(nodes: DataNode[], config: SimpleModeConfig): DataNode[] {
7+
const { id, pId, rootPId } = config;
8+
const nodeMap = new Map<string, DataNode>();
9+
const rootNodes: DataNode[] = [];
10+
11+
nodes.forEach(node => {
12+
const nodeKey = node[id];
13+
const clonedNode = { ...node, key: node.key || nodeKey };
14+
nodeMap.set(nodeKey, clonedNode);
2015
});
2116

22-
// Connect tree
23-
nodeList.forEach(node => {
17+
nodeMap.forEach(node => {
2418
const parentKey = node[pId];
25-
const parent = keyNodes[parentKey];
19+
const parent = nodeMap.get(parentKey);
2620

27-
// Fill parent
2821
if (parent) {
2922
parent.children = parent.children || [];
3023
parent.children.push(node);
31-
}
32-
33-
// Fill root tree node
34-
if (parentKey === rootPId || (!parent && rootPId === null)) {
35-
rootNodeList.push(node);
24+
} else if (parentKey === rootPId || rootPId === null) {
25+
rootNodes.push(node);
3626
}
3727
});
3828

39-
return rootNodeList;
29+
return rootNodes;
4030
}
4131

4232
/**
43-
* Convert `treeData` or `children` into formatted `treeData`.
44-
* Will not re-calculate if `treeData` or `children` not change.
33+
* `treeData` `children` 转换为格式化的 `treeData`
34+
* 如果 `treeData` `children` 没有变化,则不会重新计算。
4535
*/
4636
export default function useTreeData(
4737
treeData: DataNode[],
@@ -50,14 +40,16 @@ export default function useTreeData(
5040
): DefaultOptionType[] {
5141
return React.useMemo(() => {
5242
if (treeData) {
53-
return simpleMode
54-
? parseSimpleTreeData(treeData, {
55-
id: 'id',
56-
pId: 'pId',
57-
rootPId: null,
58-
...(simpleMode !== true ? simpleMode : {}),
59-
})
60-
: treeData;
43+
if (simpleMode) {
44+
const config: SimpleModeConfig = {
45+
id: 'id',
46+
pId: 'pId',
47+
rootPId: null,
48+
...(typeof simpleMode === 'object' ? simpleMode : {}),
49+
};
50+
return buildTreeStructure(treeData, config);
51+
}
52+
return treeData;
6153
}
6254

6355
return convertChildrenToData(children);

src/utils/valueUtil.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,10 @@ export function toArray<T>(value: T | T[]): T[] {
1010

1111
export function fillFieldNames(fieldNames?: FieldNames) {
1212
const { label, value, children } = fieldNames || {};
13-
14-
const mergedValue = value || 'value';
15-
1613
return {
1714
_title: label ? [label] : ['title', 'label'],
18-
value: mergedValue,
19-
key: mergedValue,
15+
value: value || 'value',
16+
key: value || 'value',
2017
children: children || 'children',
2118
};
2219
}

0 commit comments

Comments
 (0)