Hi @diogofcunha !
I have spent the last two days dealing with performance with many nested rows. As a result, I also found react-virtualized
. But another research showed that it doesn't work with tree's. Then I found your repository, a plugin for react-virtualized
that allows to virtualize tree's.
Over the last year I have created my own implementation of a complete React Tree Component solution (expect virtualization). This component is currently private-only accessible (not published on GitHub) because it isn't that good documentated atm. I am using it within my WordPress plugin... I'll just show you the component:
![](https://camo.githubusercontent.com/cf18f79c9ea4d69716cce64346a21b9e97d5137a71d871dc316b30e9250ffa22/68747470733a2f2f692e696d6775722e636f6d2f7a4572577766422e706e67)
On the left you can see the tree component. My question is now, is it possible to use your virtualization methodic within another React Tree Component. Just to give a brief insight, so my tree is built like this:
/**
* Render a tree.
*
* @param {object[]} tree The tree
* @param {boolean} [displayChildren=true] If true the first nodes can have childNodes
* @param {object} [createRoot] Shows an additional node after the last one with an input field
* @param {string('tree','static','search')} [context='tree'] The tree context
* @method
*/
renderTree = (tree, displayChildren = true, createRoot = undefined, context = 'tree') => {
const nodeAttr = { renderItem, onRenameClose, onAddClose, onSelect, onNodePressF2, renameSaveText, renameAddText } = this.props,
{ isTreeLinkDisabled, rootId, toggleExpandAll } = this.props,
resultSelectedNodeIdx = this.state.resultSelectedNodeIdx,
resultTreeLength = typeof resultSelectedNodeIdx === "number" && this.state.resultTree.length,
expandedState = this.storage.getItem('expandNodes') || {},
className = classNames({
'aiot-disable-links': isTreeLinkDisabled,
'aiot-sortable-one': tree.length === 1
}, 'aiot-context-' + context);
let i = -1, anyNodeHasChildren = tree.some(n => n.childNodes?.length > 0);
return [
// "All" expander
context === 'tree' && anyNodeHasChildren && ( <div key="all-expander" onClick={ this.handleToggleAll }
className={ classNames('aiot-expander', 'aiot-expander-all', { 'aiot-open': this.getExpandedNodes(expandedState).length }) } /> ),
// List view
<ul key="list-view" className={ className } data-childs-for={ rootId } ref={ displayChildren ? this.handleSortableTree : undefined }>
{ tree.map(node => {
i++;
const searchSelected = i % resultTreeLength === resultSelectedNodeIdx % resultTreeLength && !displayChildren,
propSearchSelected = context === 'search' ? searchSelected : undefined;
const createTreeNode = () => (<TreeNode key={ node.id } searchSelected={ propSearchSelected } {...node} onExpand={ this.handleNodeExpand }
expandedState={ expandedState } {...nodeAttr} onUlRef={ displayChildren ? this.handleSortableTree : undefined } displayChildren={ displayChildren } onPaging={ this.handlePaging } />);
if (renderItem) {
/**
* This function is called when a node item gets rendered.
*
* @callback module:react-aiot~Tree~renderItem
* @param {function} createTreeNode A function that creates the default tree node (helpful for wrapper functions)
* @param {module:react-aiot/components/TreeNode} TreeNode The ReactJS element
* @param {object} node The node item
* @returns {module:react-aiot/components/TreeNode}
*/
return renderItem(createTreeNode, TreeNode, node);
}else{
return createTreeNode();
}
} ) }
{ !!createRoot && <TreeNode $_create onRenameClose={ onAddClose } renameSaveText={ this.props.renameAddText } {...createRoot} /> }
</ul> ];
}
Don't be scared, but basically the top tree is just rendered and within TreeNode
a new tree is built recursively. The TreeNode
is a simple <li>
. I hope I don't overwhelm you, but right now I'm a bit desperate about virtualization with nested trees. If my component is also able to virtualize, I think about making it open source.
Best regards,
Matthew :-)