Skip to content

Commit 4e69578

Browse files
committed
Adjust loadData logic
2 parents e889780 + bd7619e commit 4e69578

File tree

6 files changed

+108
-90
lines changed

6 files changed

+108
-90
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "rc-tree",
3-
"version": "1.13.1",
3+
"version": "1.13.2",
44
"description": "tree ui component for react",
55
"keywords": [
66
"react",

src/Tree.jsx

Lines changed: 37 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -510,39 +510,46 @@ class Tree extends React.Component {
510510
}
511511
};
512512

513-
onNodeLoad = (treeNode) => {
514-
const { loadData, onLoad } = this.props;
515-
const { loadedKeys = [], loadingKeys = [] } = this.state;
516-
const { eventKey } = treeNode.props;
517-
518-
if (!loadData || loadedKeys.indexOf(eventKey) !== -1 || loadingKeys.indexOf(eventKey) !== -1) {
519-
return null;
520-
}
513+
onNodeLoad = treeNode => (
514+
new Promise((resolve) => {
515+
// We need to get the latest state of loading/loaded keys
516+
this.setState(({ loadedKeys = [], loadingKeys = [] }) => {
517+
const { loadData, onLoad } = this.props;
518+
const { eventKey } = treeNode.props;
519+
520+
if (!loadData || loadedKeys.indexOf(eventKey) !== -1 || loadingKeys.indexOf(eventKey) !== -1) {
521+
// react 15 will warn if return null
522+
return {};
523+
}
521524

522-
this.setState({
523-
loadingKeys: arrAdd(loadingKeys, eventKey),
524-
});
525-
const promise = loadData(treeNode);
526-
promise.then(() => {
527-
const newLoadedKeys = arrAdd(this.state.loadedKeys, eventKey);
528-
this.setUncontrolledState({
529-
loadedKeys: newLoadedKeys,
530-
});
531-
this.setState({
532-
loadingKeys: arrDel(this.state.loadingKeys, eventKey),
533-
});
525+
// Process load data
526+
const promise = loadData(treeNode);
527+
promise.then(() => {
528+
const newLoadedKeys = arrAdd(this.state.loadedKeys, eventKey);
529+
this.setUncontrolledState({
530+
loadedKeys: newLoadedKeys,
531+
});
532+
this.setState({
533+
loadingKeys: arrDel(this.state.loadingKeys, eventKey),
534+
});
535+
536+
if (onLoad) {
537+
const eventObj = {
538+
event: 'load',
539+
node: treeNode,
540+
};
541+
onLoad(newLoadedKeys, eventObj);
542+
}
543+
544+
resolve();
545+
});
534546

535-
if (onLoad) {
536-
const eventObj = {
537-
event: 'load',
538-
node: treeNode,
547+
return {
548+
loadingKeys: arrAdd(loadingKeys, eventKey),
539549
};
540-
onLoad(newLoadedKeys, eventObj);
541-
}
542-
});
543-
544-
return promise;
545-
};
550+
});
551+
})
552+
);
546553

547554
onNodeExpand = (e, treeNode) => {
548555
let { expandedKeys } = this.state;

src/TreeNode.jsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,9 +274,11 @@ class TreeNode extends React.Component {
274274

275275
// Load data to avoid default expanded tree without data
276276
syncLoadData = (props) => {
277-
const { expanded } = props;
277+
const { expanded, loading } = props;
278278
const { rcTree: { onNodeLoad } } = this.context;
279279

280+
if (loading) return;
281+
280282
// read from state to avoid loadData at same time
281283
if (expanded && !this.isLeaf()) {
282284
// We needn't reload data when has children in sync logic

src/util.js

Lines changed: 1 addition & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -95,30 +95,6 @@ export function mapChildren(children, func) {
9595
return list;
9696
}
9797

98-
/**
99-
* Check position relation.
100-
* @param parentPos
101-
* @param childPos
102-
* @param directly only directly parent can be true
103-
* @returns {boolean}
104-
*/
105-
export function isParent(parentPos, childPos, directly = false) {
106-
if (!parentPos || !childPos || parentPos.length > childPos.length) return false;
107-
108-
const parentPath = posToArr(parentPos);
109-
const childPath = posToArr(childPos);
110-
111-
// Directly check
112-
if (directly && parentPath.length !== childPath.length - 1) return false;
113-
114-
const len = parentPath.length;
115-
for (let i = 0; i < len; i += 1) {
116-
if (parentPath[i] !== childPath[i]) return false;
117-
}
118-
119-
return true;
120-
}
121-
12298
export function getDragNodesKeys(treeNodes, node) {
12399
const { eventKey, pos } = node.props;
124100
const dragNodesKeys = [];
@@ -256,7 +232,7 @@ export function parseCheckedKeys(keys) {
256232
halfCheckedKeys: keys.halfChecked || undefined,
257233
};
258234
} else {
259-
warning(false, '`CheckedKeys` is not an array or an object');
235+
warning(false, '`checkedKeys` is not an array or an object');
260236
return null;
261237
}
262238

tests/TreeProps.spec.js

Lines changed: 65 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -401,49 +401,82 @@ describe('Tree Props', () => {
401401
// defaultCheckedKeys - is already full test in Tree.spec.js
402402
// defaultSelectedKeys - is already full test in Tree.spec.js
403403

404-
it('loadData', () => {
405-
let called = 0;
404+
describe('loadData', () => {
405+
it('basic', () => {
406+
let called = 0;
406407

407-
const handleLoadData = jest.fn();
408+
const handleLoadData = jest.fn();
408409

409-
class Demo extends React.Component {
410-
state = {
411-
loaded: false,
412-
};
410+
class Demo extends React.Component {
411+
state = {
412+
loaded: false,
413+
};
413414

414-
loadData = (...args) => {
415-
called += 1;
416-
handleLoadData(...args);
415+
loadData = (...args) => {
416+
called += 1;
417+
handleLoadData(...args);
417418

418-
this.setState({ loaded: true });
419+
this.setState({ loaded: true });
419420

420-
return Promise.resolve();
421-
};
421+
return Promise.resolve();
422+
};
422423

423-
render() {
424-
// Hide icon will still show the icon for loading status
425-
return (
426-
<Tree loadData={this.loadData} showIcon={false}>
427-
<TreeNode key="0-0">
428-
{this.state.loaded ? <TreeNode key="0-0-0" /> : null}
429-
</TreeNode>
430-
</Tree>
431-
);
424+
render() {
425+
// Hide icon will still show the icon for loading status
426+
return (
427+
<Tree loadData={this.loadData} showIcon={false}>
428+
<TreeNode key="0-0">
429+
{this.state.loaded ? <TreeNode key="0-0-0" /> : null}
430+
</TreeNode>
431+
</Tree>
432+
);
433+
}
432434
}
433-
}
434435

435-
const wrapper = mount(<Demo />);
436+
const wrapper = mount(<Demo />);
436437

437-
expect(handleLoadData).not.toBeCalled();
438+
expect(handleLoadData).not.toBeCalled();
439+
440+
const switcher = wrapper.find('.rc-tree-switcher');
441+
const node = wrapper.find(TreeNode).instance();
442+
switcher.simulate('click');
443+
444+
return timeoutPromise().then(() => {
445+
expect(handleLoadData).toBeCalledWith(node);
446+
expect(called).toBe(1);
447+
expect(renderToJson(wrapper.render())).toMatchSnapshot();
448+
});
449+
});
438450

439-
const switcher = wrapper.find('.rc-tree-switcher');
440-
const node = wrapper.find(TreeNode).instance();
441-
switcher.simulate('click');
451+
// https://github.com/ant-design/ant-design/issues/11689#issuecomment-411712770
452+
it('with expandedKeys', () => {
453+
let called = 0;
454+
const keys = {};
455+
const loadData = ({ props: { eventKey } }) => {
456+
keys[eventKey] = (keys[eventKey] || 0) + 1;
442457

443-
return timeoutPromise().then(() => {
444-
expect(handleLoadData).toBeCalledWith(node);
445-
expect(called).toBe(1);
446-
expect(renderToJson(wrapper.render())).toMatchSnapshot();
458+
return new Promise(() => {
459+
called += 1;
460+
});
461+
};
462+
463+
mount(
464+
<Tree
465+
loadData={loadData}
466+
expandedKeys={['0', '1', '2']}
467+
>
468+
<TreeNode key="0" />
469+
<TreeNode key="1" />
470+
<TreeNode key="2" />
471+
</Tree>
472+
);
473+
474+
return timeoutPromise().then(() => {
475+
expect(called).toBe(3);
476+
expect(keys[0]).toBe(1);
477+
expect(keys[1]).toBe(1);
478+
expect(keys[2]).toBe(1);
479+
});
447480
});
448481
});
449482

tests/__snapshots__/TreeProps.spec.js.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -761,7 +761,7 @@ exports[`Tree Props invalidate checkedKeys number 1`] = `
761761
</ul>
762762
`;
763763

764-
exports[`Tree Props loadData 1`] = `
764+
exports[`Tree Props loadData basic 1`] = `
765765
<ul
766766
class="rc-tree"
767767
role="tree"

0 commit comments

Comments
 (0)