tree-select
tree-select copied to clipboard
Dynamic Load Data does not render children on expand
I am following the dynamic.html example and have a handler for the loadData property. In this handler we are dynamically fetching the children and inserting them in the "children" property of the appropriate node in the treeData array that is in the State object of our component that is embedding TreeSelect. Here are some snippets of code: Render method: render() { this.disableCurrNode(this.state.treeData); return ( <TreeSelect style={{ width: '100%' }} dropdownStyle={{ maxHeight: 200, overflow: 'auto' }} placeholder={this.props.intl.formatMessage(messages.searchFolderPlaceholder)} treeIcon={true} treeCheckable={false} showSearch={false} multiple={false} inputValue={null} value={this.state.value} treeData={this.state.treeData} treeDataSimpleMode={false} onChange={this.onChange} loadData={this.onLoadData} /> ); }
Load Data hander:
onLoadData = (treeNode) => {
return new Promise((resolve) => {
const self = this;
const entityId = treeNode.props.value;
const token = this.props.token;
$.getJSON(/box-admin/box-ui-proxy/treeChildFolders/${ entityId }?token=${ token}
, (data) => {
const treeData = self.state.treeData;
self.recursiveAddChildren(entityId, treeData, data.items);
self.disableCurrNode(treeData);
self.setState({
treeData
});
resolve();
});
});
};
The TreeSelect is in a react modal dialog, the first time the tree is expanded it does not show the children, but if I subsequently close the dialog and open again it show the children.
The following screenshots shows the issue:
First Time the Tree Node is expanded (Collaboration Test):
Second Time the Tree node is expanded (Collaboration Test):
@sghosh326 @ratbeard
We had to work around this by doing 2 things:
- in the
loadData
function, we allowed for the promise to be completed, and then added that node's key to theexpandedKey
array which we are managing the full state of. This effectively expands the node after the async ajax call has updated the tree data's state, thus, rendering the ajax content on expansion.
The onExpand function fires on: expansion and collapse, but before the ajax activity completes from loadData
, so we avoid adding the key to the expandedKey
array on the initial load, but manage it with the following.
- In the
onExpand
function, we do a couple things: 2.1. If the node is!event.expanded
, remove it from theexpandedKey
array. 2.2. If the node isevent.node.props.loaded
, we have a loaded node we can expand, without clashing with theloadData
event that fires on the first expansion by design. Otherwise, you'd be firing the expansion twice, which depending on implementation could be an infinite loop (in our case).
It's a little janky, probably wouldn't be hard to make a PR to make this behave more predictably.
Update, I suspect this issue actually belongs here - https://github.com/react-component/tree / https://github.com/react-component/tree/blob/master/src/Tree.jsx#L585 / https://github.com/react-component/tree/blob/master/src/Tree.jsx#L600.