I'm fairly new to React, Redux and ImmutableJS, and have run into some performance issues.
I have a large tree structure of data, which I'm currently storing as a flat list in this structure:
new Map({
1: new Node({
id: 1,
text: 'Root',
children: [2,3]
}),
2: new Node({
id: 2,
text: 'Child 1',
children: [4]
}),
3: new Node({
id: 3,
text: 'Child 2',
children: []
}),
4: new Node({
id: 4,
text: 'Child of child 1',
children: []
})
});
While structuring it as a flat list makes updating nodes easy, I'm finding that interaction gets sluggish as the tree grows. Interaction includes being able to select one or more nodes, toggle the visibility of their child nodes, update the text, and so on. It looks like a key reason for the the sluggish UI is that the entire tree is being redrawn for each interaction.
I want to use shouldComponentUpdate
such that if I update node 3, nodes 2 and 4 do not update. This would be easy if the data was stored as a tree (I could simply check whether this.props !== nextProps
), but as the data is stored in a flat list the check would be substantially more complex.
How should I being storing the data and using shouldComponentUpdate
(or other methods) to support a smooth UI with hundreds or thousands of tree nodes?
Edit
I've been connecting the store at the top level, and then having to pass the entire store down to subcomponents.
My structure is:
<NodeTree>
<NodeBranch>
<Node>{{text}}</Node>
<NodeTree>...</NodeTree>
</NodeBranch>
<NodeBranch>
<Node>{{text}}</Node>
<NodeTree>...</NodeTree>
</NodeBranch>
...
</NodeTree>
The <Node>
can do a simple check with shouldComponentUpdate
to see if the title has changed, but I have no similar solution to use on the <NodeTree>
or <NodeBranch>
given the recursive nature of the tree.
It looks like the best solution (thanks @Dan Abramov) would be to connect each <NodeBranch>
, rather just connecting at the top level. I'll be testing this this evening.