Skip to content

Commit 9de5d2f

Browse files
authored
fix: treeNodeLabelProp should only work on result value (#250)
* use hooks * fix: treeNodeLabelProp should only work on result value
1 parent 7bd486c commit 9de5d2f

File tree

4 files changed

+79
-18
lines changed

4 files changed

+79
-18
lines changed

examples/treeNodeLabelProp.tsx

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import '../assets/index.less';
2+
import React from 'react';
3+
import TreeSelect, { TreeNode } from '../src';
4+
5+
const treeData = [
6+
{
7+
title: 'a list is option only',
8+
showTitle: 'Node2',
9+
value: '0-1',
10+
},
11+
];
12+
13+
function Demo() {
14+
return (
15+
<>
16+
<TreeSelect
17+
style={{ width: '100%' }}
18+
treeDefaultExpandAll
19+
treeData={treeData}
20+
treeNodeLabelProp="showTitle"
21+
/>
22+
<TreeSelect style={{ width: '100%' }} treeDefaultExpandAll treeNodeLabelProp="showTitle">
23+
<TreeNode value="0-0" title="a list is option only" showTitle="Node2" />
24+
</TreeSelect>
25+
</>
26+
);
27+
}
28+
29+
export default Demo;

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@
6767
"@babel/runtime": "^7.10.1",
6868
"classnames": "2.x",
6969
"rc-select": "^11.0.4",
70-
"rc-tree": "^3.6.0",
71-
"rc-util": "^5.0.1"
70+
"rc-tree": "^3.8.0",
71+
"rc-util": "^5.0.5"
7272
}
7373
}

src/TreeSelect.tsx

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
import React from 'react';
1+
import * as React from 'react';
2+
import { useMemo } from 'react';
23
import generateSelector, { SelectProps, RefSelectProps } from 'rc-select/lib/generate';
34
import { getLabeledValue } from 'rc-select/lib/utils/valueUtil';
45
import { convertDataToEntities } from 'rc-tree/lib/utils/treeUtil';
56
import { conductCheck } from 'rc-tree/lib/utils/conductUtil';
67
import { IconType } from 'rc-tree/lib/interface';
78
import { FilterFunc, INTERNAL_PROPS_MARK } from 'rc-select/lib/interface/generator';
9+
import useMergedState from 'rc-util/lib/hooks/useMergedState';
810
import warning from 'rc-util/lib/warning';
911
import OptionList from './OptionList';
1012
import TreeNode from './TreeNode';
@@ -206,37 +208,42 @@ const RefTreeSelect = React.forwardRef<RefSelectProps, TreeSelectProps>((props,
206208
// ======================= Tree Data =======================
207209
// Legacy both support `label` or `title` if not set.
208210
// We have to fallback to function to handle this
211+
const getTreeNodeTitle = (node: DataNode): React.ReactNode => {
212+
if (!treeData) {
213+
return node.title;
214+
}
215+
return node.label || node.title;
216+
};
217+
209218
const getTreeNodeLabelProp = (node: DataNode): React.ReactNode => {
210219
if (treeNodeLabelProp) {
211220
return node[treeNodeLabelProp];
212221
}
213222

214-
if (!treeData) {
215-
return node.title;
216-
}
217-
return node.label || node.title;
223+
return getTreeNodeTitle(node);
218224
};
219225

220226
const mergedTreeData = useTreeData(treeData, children, {
221-
getLabelProp: getTreeNodeLabelProp,
227+
getLabelProp: getTreeNodeTitle,
222228
simpleMode: treeDataSimpleMode,
223229
});
224230

225-
const flattedOptions = React.useMemo(() => flattenOptions(mergedTreeData), [mergedTreeData]);
231+
const flattedOptions = useMemo(() => flattenOptions(mergedTreeData), [mergedTreeData]);
226232
const [cacheKeyMap, cacheValueMap] = useKeyValueMap(flattedOptions);
227233
const [getEntityByKey, getEntityByValue] = useKeyValueMapping(cacheKeyMap, cacheValueMap);
228234

229235
// Only generate keyEntities for check conduction when is `treeCheckable`
230-
const { keyEntities: conductKeyEntities } = React.useMemo(() => {
236+
const { keyEntities: conductKeyEntities } = useMemo(() => {
231237
if (treeConduction) {
232238
return convertDataToEntities(mergedTreeData as any);
233239
}
234240
return { keyEntities: null };
235241
}, [mergedTreeData, treeCheckable, treeCheckStrictly]);
236242

237243
// ========================= Value =========================
238-
const [value, setValue] = React.useState<DefaultValueType>(props.defaultValue);
239-
const mergedValue = 'value' in props ? props.value : value;
244+
const [value, setValue] = useMergedState<DefaultValueType>(props.defaultValue, {
245+
value: props.value,
246+
});
240247

241248
/** Get `missingRawValues` which not exist in the tree yet */
242249
const splitRawValues = (newRawValues: RawValueType[]) => {
@@ -255,11 +262,11 @@ const RefTreeSelect = React.forwardRef<RefSelectProps, TreeSelectProps>((props,
255262
return { missingRawValues, existRawValues };
256263
};
257264

258-
const [rawValues, rawHalfCheckedKeys]: [RawValueType[], RawValueType[]] = React.useMemo(() => {
265+
const [rawValues, rawHalfCheckedKeys]: [RawValueType[], RawValueType[]] = useMemo(() => {
259266
const valueHalfCheckedKeys: RawValueType[] = [];
260267
const newRawValues: RawValueType[] = [];
261268

262-
toArray(mergedValue).forEach(item => {
269+
toArray(value).forEach(item => {
263270
if (item && typeof item === 'object' && 'value' in item) {
264271
if (item.halfChecked && treeCheckStrictly) {
265272
const entity = getEntityByValue(item.value);
@@ -284,10 +291,10 @@ const RefTreeSelect = React.forwardRef<RefSelectProps, TreeSelectProps>((props,
284291
];
285292
}
286293
return [newRawValues, valueHalfCheckedKeys];
287-
}, [mergedValue, mergedMultiple, mergedLabelInValue, treeCheckable, treeCheckStrictly]);
294+
}, [value, mergedMultiple, mergedLabelInValue, treeCheckable, treeCheckStrictly]);
288295
const selectValues = useSelectValues(rawValues, {
289296
treeConduction,
290-
value: mergedValue,
297+
value,
291298
showCheckedStrategy,
292299
conductKeyEntities,
293300
getEntityByValue,
@@ -326,7 +333,7 @@ const RefTreeSelect = React.forwardRef<RefSelectProps, TreeSelectProps>((props,
326333
};
327334

328335
let returnValues = mergedLabelInValue
329-
? getRawValueLabeled(eventValues, mergedValue, getEntityByValue, getTreeNodeLabelProp)
336+
? getRawValueLabeled(eventValues, value, getEntityByValue, getTreeNodeLabelProp)
330337
: eventValues;
331338

332339
// We need fill half check back
@@ -340,7 +347,7 @@ const RefTreeSelect = React.forwardRef<RefSelectProps, TreeSelectProps>((props,
340347

341348
returnValues = [
342349
...(returnValues as LabelValueType[]),
343-
...getRawValueLabeled(halfValues, mergedValue, getEntityByValue, getTreeNodeLabelProp),
350+
...getRawValueLabeled(halfValues, value, getEntityByValue, getTreeNodeLabelProp),
344351
];
345352
}
346353

tests/Select.tree.spec.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,4 +100,29 @@ describe('TreeSelect.tree', () => {
100100

101101
expect(wrapper.getSelection(0).text()).toEqual('empty string');
102102
});
103+
104+
describe('treeNodeLabelProp', () => {
105+
[
106+
{ name: 'treeDate', treeData: [{ title: 'a light', op: 'Light', value: 'light' }] },
107+
{
108+
name: 'children',
109+
children: <SelectNode title="a light" op="Light" value="light" />,
110+
},
111+
].forEach(({ name, ...restProps }) => {
112+
it(name, () => {
113+
const wrapper = mount(
114+
<TreeSelect
115+
open
116+
treeDefaultExpandAll
117+
treeNodeLabelProp="op"
118+
value="light"
119+
{...restProps}
120+
/>,
121+
);
122+
123+
expect(wrapper.find('.rc-tree-select-tree-title').text()).toEqual('a light');
124+
expect(wrapper.find('.rc-tree-select-selection-item').text()).toEqual('Light');
125+
});
126+
});
127+
});
103128
});

0 commit comments

Comments
 (0)