diff --git a/examples/treeNodeLabelProp.tsx b/examples/treeNodeLabelProp.tsx
new file mode 100644
index 00000000..b679d760
--- /dev/null
+++ b/examples/treeNodeLabelProp.tsx
@@ -0,0 +1,29 @@
+import '../assets/index.less';
+import React from 'react';
+import TreeSelect, { TreeNode } from '../src';
+
+const treeData = [
+ {
+ title: 'a list is option only',
+ showTitle: 'Node2',
+ value: '0-1',
+ },
+];
+
+function Demo() {
+ return (
+ <>
+
+
+
+
+ >
+ );
+}
+
+export default Demo;
diff --git a/package.json b/package.json
index 477b26e2..3380dbad 100644
--- a/package.json
+++ b/package.json
@@ -67,7 +67,7 @@
"@babel/runtime": "^7.10.1",
"classnames": "2.x",
"rc-select": "^11.0.4",
- "rc-tree": "^3.6.0",
- "rc-util": "^5.0.1"
+ "rc-tree": "^3.8.0",
+ "rc-util": "^5.0.5"
}
}
diff --git a/src/TreeSelect.tsx b/src/TreeSelect.tsx
index ce8f4b25..4701ad4d 100644
--- a/src/TreeSelect.tsx
+++ b/src/TreeSelect.tsx
@@ -1,10 +1,12 @@
-import React from 'react';
+import * as React from 'react';
+import { useMemo } from 'react';
import generateSelector, { SelectProps, RefSelectProps } from 'rc-select/lib/generate';
import { getLabeledValue } from 'rc-select/lib/utils/valueUtil';
import { convertDataToEntities } from 'rc-tree/lib/utils/treeUtil';
import { conductCheck } from 'rc-tree/lib/utils/conductUtil';
import { IconType } from 'rc-tree/lib/interface';
import { FilterFunc, INTERNAL_PROPS_MARK } from 'rc-select/lib/interface/generator';
+import useMergedState from 'rc-util/lib/hooks/useMergedState';
import warning from 'rc-util/lib/warning';
import OptionList from './OptionList';
import TreeNode from './TreeNode';
@@ -206,28 +208,32 @@ const RefTreeSelect = React.forwardRef((props,
// ======================= Tree Data =======================
// Legacy both support `label` or `title` if not set.
// We have to fallback to function to handle this
+ const getTreeNodeTitle = (node: DataNode): React.ReactNode => {
+ if (!treeData) {
+ return node.title;
+ }
+ return node.label || node.title;
+ };
+
const getTreeNodeLabelProp = (node: DataNode): React.ReactNode => {
if (treeNodeLabelProp) {
return node[treeNodeLabelProp];
}
- if (!treeData) {
- return node.title;
- }
- return node.label || node.title;
+ return getTreeNodeTitle(node);
};
const mergedTreeData = useTreeData(treeData, children, {
- getLabelProp: getTreeNodeLabelProp,
+ getLabelProp: getTreeNodeTitle,
simpleMode: treeDataSimpleMode,
});
- const flattedOptions = React.useMemo(() => flattenOptions(mergedTreeData), [mergedTreeData]);
+ const flattedOptions = useMemo(() => flattenOptions(mergedTreeData), [mergedTreeData]);
const [cacheKeyMap, cacheValueMap] = useKeyValueMap(flattedOptions);
const [getEntityByKey, getEntityByValue] = useKeyValueMapping(cacheKeyMap, cacheValueMap);
// Only generate keyEntities for check conduction when is `treeCheckable`
- const { keyEntities: conductKeyEntities } = React.useMemo(() => {
+ const { keyEntities: conductKeyEntities } = useMemo(() => {
if (treeConduction) {
return convertDataToEntities(mergedTreeData as any);
}
@@ -235,8 +241,9 @@ const RefTreeSelect = React.forwardRef((props,
}, [mergedTreeData, treeCheckable, treeCheckStrictly]);
// ========================= Value =========================
- const [value, setValue] = React.useState(props.defaultValue);
- const mergedValue = 'value' in props ? props.value : value;
+ const [value, setValue] = useMergedState(props.defaultValue, {
+ value: props.value,
+ });
/** Get `missingRawValues` which not exist in the tree yet */
const splitRawValues = (newRawValues: RawValueType[]) => {
@@ -255,11 +262,11 @@ const RefTreeSelect = React.forwardRef((props,
return { missingRawValues, existRawValues };
};
- const [rawValues, rawHalfCheckedKeys]: [RawValueType[], RawValueType[]] = React.useMemo(() => {
+ const [rawValues, rawHalfCheckedKeys]: [RawValueType[], RawValueType[]] = useMemo(() => {
const valueHalfCheckedKeys: RawValueType[] = [];
const newRawValues: RawValueType[] = [];
- toArray(mergedValue).forEach(item => {
+ toArray(value).forEach(item => {
if (item && typeof item === 'object' && 'value' in item) {
if (item.halfChecked && treeCheckStrictly) {
const entity = getEntityByValue(item.value);
@@ -284,10 +291,10 @@ const RefTreeSelect = React.forwardRef((props,
];
}
return [newRawValues, valueHalfCheckedKeys];
- }, [mergedValue, mergedMultiple, mergedLabelInValue, treeCheckable, treeCheckStrictly]);
+ }, [value, mergedMultiple, mergedLabelInValue, treeCheckable, treeCheckStrictly]);
const selectValues = useSelectValues(rawValues, {
treeConduction,
- value: mergedValue,
+ value,
showCheckedStrategy,
conductKeyEntities,
getEntityByValue,
@@ -326,7 +333,7 @@ const RefTreeSelect = React.forwardRef((props,
};
let returnValues = mergedLabelInValue
- ? getRawValueLabeled(eventValues, mergedValue, getEntityByValue, getTreeNodeLabelProp)
+ ? getRawValueLabeled(eventValues, value, getEntityByValue, getTreeNodeLabelProp)
: eventValues;
// We need fill half check back
@@ -340,7 +347,7 @@ const RefTreeSelect = React.forwardRef((props,
returnValues = [
...(returnValues as LabelValueType[]),
- ...getRawValueLabeled(halfValues, mergedValue, getEntityByValue, getTreeNodeLabelProp),
+ ...getRawValueLabeled(halfValues, value, getEntityByValue, getTreeNodeLabelProp),
];
}
diff --git a/tests/Select.tree.spec.js b/tests/Select.tree.spec.js
index 89a7d458..6628dea3 100644
--- a/tests/Select.tree.spec.js
+++ b/tests/Select.tree.spec.js
@@ -100,4 +100,29 @@ describe('TreeSelect.tree', () => {
expect(wrapper.getSelection(0).text()).toEqual('empty string');
});
+
+ describe('treeNodeLabelProp', () => {
+ [
+ { name: 'treeDate', treeData: [{ title: 'a light', op: 'Light', value: 'light' }] },
+ {
+ name: 'children',
+ children: ,
+ },
+ ].forEach(({ name, ...restProps }) => {
+ it(name, () => {
+ const wrapper = mount(
+ ,
+ );
+
+ expect(wrapper.find('.rc-tree-select-tree-title').text()).toEqual('a light');
+ expect(wrapper.find('.rc-tree-select-selection-item').text()).toEqual('Light');
+ });
+ });
+ });
});