Skip to content

fix: onExpand should check if children tree node loaded #831

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion src/Tree.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import {
SafeKey,
ScrollTo,
} from './interface';
import NodeList, { MotionEntity, MOTION_KEY, NodeListRef } from './NodeList';
import NodeList, { MOTION_KEY, MotionEntity, NodeListRef } from './NodeList';
import TreeNode from './TreeNode';
import {
arrAdd,
Expand Down Expand Up @@ -957,6 +957,13 @@ class Tree<TreeDataType extends DataNode | BasicDataNode = DataNode> extends Rea

onNodeLoad = (treeNode: EventDataNode<TreeDataType>) => {
const { key } = treeNode;
const { keyEntities } = this.state;

// Skip if has children already
const entity = getEntity(keyEntities, key);
if (entity?.children?.length) {
return;
}

const loadPromise = new Promise<void>((resolve, reject) => {
// We need to get the latest state of loading/loaded keys
Expand Down
16 changes: 10 additions & 6 deletions src/TreeNode.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ class InternalTreeNode extends React.Component<InternalTreeNodeProps, TreeNodeSt
};

// Load data to avoid default expanded tree without data
syncLoadData = props => {
syncLoadData = (props: InternalTreeNodeProps) => {
const { expanded, loading, loaded } = props;
const {
context: { loadData, onNodeLoad },
Expand All @@ -262,12 +262,10 @@ class InternalTreeNode extends React.Component<InternalTreeNodeProps, TreeNodeSt
}

// read from state to avoid loadData at same time
if (loadData && expanded && !this.isLeaf()) {
if (loadData && expanded && !this.isLeaf() && !loaded) {
// We needn't reload data when has children in sync logic
// It's only needed in node expanded
if (!this.hasChildren() && !loaded) {
onNodeLoad(convertNodePropsToEventData(this.props));
}
onNodeLoad(convertNodePropsToEventData(this.props));
}
};

Expand Down Expand Up @@ -582,7 +580,13 @@ class InternalTreeNode extends React.Component<InternalTreeNodeProps, TreeNodeSt
{...ariaSelected}
{...dataOrAriaAttributeProps}
>
<Indent prefixCls={prefixCls} level={level} isStart={isStart} isEnd={isEnd} width={indentWidth} />
<Indent
prefixCls={prefixCls}
level={level}
isStart={isStart}
isEnd={isEnd}
width={indentWidth}
/>
{this.renderDragHandler()}
{this.renderSwitcher()}
{this.renderCheckbox()}
Expand Down
55 changes: 44 additions & 11 deletions tests/TreeProps.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -559,7 +559,7 @@ describe('Tree Props', () => {
</Tree>,
);

fireEvent.click(container.querySelector('.rc-tree-switcher'));
fireEvent.click(container.querySelector('.rc-tree-switcher')!);

expect(onExpand).toHaveBeenCalled();

Expand Down Expand Up @@ -614,14 +614,14 @@ describe('Tree Props', () => {
const { container } = render(<Test />);

// Parent click
fireEvent.click(container.querySelector('.rc-tree-switcher'));
fireEvent.click(container.querySelector('.rc-tree-switcher')!);

setTimeout(() => {
// Child click
fireEvent.click(container.querySelectorAll('.rc-tree-switcher')[1]);

setTimeout(() => {
expect(count).toBe(2);
expect(count).toBe(1);
done();
}, 500);
}, 500);
Expand Down Expand Up @@ -654,6 +654,37 @@ describe('Tree Props', () => {
'Warning: Retry for `loadData` many times but still failed. No more retry.',
);
});

// https://github.com/ant-design/ant-design/issues/48796
it('skip load if has children', () => {
const loadData = jest.fn(async (info) => {
console.log('->', info.key);
});

const { container } = render(
<Tree
loadedKeys={[]}
loadData={loadData}
treeData={[
{
title: 'parent',
key: 'parent',
isLeaf: false,
children: [
{
title: 'child',
key: 'child',
isLeaf: true,
},
],
},
]}
/>,
);

fireEvent.click(container.querySelector('.rc-tree-switcher')!);
expect(loadData).not.toHaveBeenCalled();
});
});

it('icon', () => {
Expand Down Expand Up @@ -693,14 +724,16 @@ describe('Tree Props', () => {

it('indentWidth', () => {
const { container } = render(
<Tree defaultExpandAll indentWidth={200}>
<TreeNode key="0-0" title="parent">
<TreeNode key="0-0-0" title="child" />
</TreeNode>
</Tree>
<Tree defaultExpandAll indentWidth={200}>
<TreeNode key="0-0" title="parent">
<TreeNode key="0-0-0" title="child" />
</TreeNode>
</Tree>,
);

expect(getComputedStyle(container.querySelector('.rc-tree-indent-unit-start')).width).toBe(
'200px',
);

expect(getComputedStyle(container.querySelector(".rc-tree-indent-unit-start")).width).toBe('200px')
});

it('onDoubleClick', () => {
Expand Down Expand Up @@ -775,7 +808,7 @@ describe('Tree Props', () => {
return new FakePromise(ret);
};

catch = () => { };
catch = () => {};
}

// eslint-disable-next-line prefer-const
Expand Down
Loading