tree-select icon indicating copy to clipboard operation
tree-select copied to clipboard

Dynamic Load Data does not render children on expand

Open sghosh326 opened this issue 6 years ago • 2 comments

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): image

Second Time the Tree node is expanded (Collaboration Test): image

sghosh326 avatar Dec 29 '18 03:12 sghosh326

@sghosh326 @ratbeard

We had to work around this by doing 2 things:

  1. in the loadData function, we allowed for the promise to be completed, and then added that node's key to the expandedKey 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.

  1. In the onExpand function, we do a couple things: 2.1. If the node is !event.expanded, remove it from the expandedKey array. 2.2. If the node is event.node.props.loaded, we have a loaded node we can expand, without clashing with the loadData 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.

bradgreens avatar Jun 10 '19 22:06 bradgreens

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.

bradgreens avatar Jun 10 '19 22:06 bradgreens