diff --git a/src/tree/TreeItem.tsx b/src/tree/TreeItem.tsx
index 476a5fc3f9..ded073df88 100644
--- a/src/tree/TreeItem.tsx
+++ b/src/tree/TreeItem.tsx
@@ -8,6 +8,7 @@ import React, {
DragEvent,
isValidElement,
useEffect,
+ useState,
} from 'react';
import classNames from 'classnames';
import isFunction from 'lodash/isFunction';
@@ -25,6 +26,7 @@ import useConfig from '../hooks/useConfig';
import type { TdTreeProps } from './type';
import type { TreeItemProps } from './interface';
+import type { TypeTreeNodeData } from '../_common/js/tree-v1/types';
/**
* 树节点组件
@@ -210,11 +212,23 @@ const TreeItem = forwardRef(
const [labelDom, setRefCurrent] = useDomRefCallback();
useRipple(labelDom);
+ // setData需要强制刷新组件来更新数据
+ const [, updateRender] = useState({});
+
const renderLabel = () => {
const emptyView = locale('empty');
let labelText: string | ReactNode = '';
if (label instanceof Function) {
- labelText = label(node.getModel()) || emptyView;
+ const { setData: nodeSetData, ...rest } = node.getModel();
+ labelText =
+ label({
+ ...rest,
+ // 拦截setData render tree-item
+ setData: (value: TypeTreeNodeData) => {
+ nodeSetData(value);
+ updateRender({});
+ },
+ }) || emptyView;
} else {
labelText = node.label || emptyView;
}
diff --git a/src/tree/__tests__/tree.test.tsx b/src/tree/__tests__/tree.test.tsx
index 2dea5c0542..fc749f67c6 100644
--- a/src/tree/__tests__/tree.test.tsx
+++ b/src/tree/__tests__/tree.test.tsx
@@ -320,4 +320,71 @@ describe('Tree test', () => {
await mockDelay(300);
expect(container.querySelectorAll('.t-loading').length).toBe(1);
});
+
+ test('custom label', async () => {
+ const data = [
+ {
+ label: '第1一段',
+ value: 1,
+ children: [
+ {
+ label: '第二段',
+ value: '1-1',
+ },
+ ],
+ },
+ {
+ label: '第二段',
+ value: 2,
+ },
+ ];
+ const { container } = await renderTreeWithProps({
+ data,
+ label: ({ data, setData }) =>
+ data.isEditing ? (
+ {
+ console.log('blur', { ...data, isEditing: false });
+ setData({ ...data, label: e.target.value, isEditing: false });
+ }}
+ onKeyDown={(e) => {
+ console.log('keydown', e.key);
+ if (e.key === 'Enter') {
+ setData({ ...data, label: e.currentTarget.value, isEditing: false });
+ console.log('Enter setData({ ...data, name: e.target.value, isEditing: false })');
+ }
+ if (e.key === 'Escape') {
+ setData({ ...data, isEditing: false });
+ console.log('ESC setData({ ...data, isEditing: false })');
+ }
+ }}
+ />
+ ) : (
+ {
+ e.stopPropagation();
+ setData({ ...data, isEditing: true });
+ }}
+ >
+ {data.label}
+
+ ),
+ });
+ await mockDelay(300);
+ expect(container.querySelector('.tree-item-span')).not.toBeNull();
+ fireEvent.dblClick(container.querySelector('.tree-item-span'));
+ await mockDelay(300);
+ expect(container.querySelector('.tree-item-input')).not.toBeNull();
+ fireEvent.change(container.querySelector('.tree-item-input'), { target: { value: '123' } });
+ expect(container.querySelector('.tree-item-input').value).toBe('123');
+ container.querySelector('.tree-item-input').focus();
+ container.querySelector('.tree-item-input').blur();
+ await mockDelay(300);
+ expect(container.querySelector('.tree-item-input')).toBeNull();
+ expect(container.querySelector('.tree-item-span')).not.toBeNull();
+ expect(container.querySelector('.tree-item-span').textContent).toBe('123');
+ });
});