Reputation: 2535
I had a CategoryPicker
component which displays a large category tree(hierarchical, about 20,000 nodes), each of the node was bound to a onClick
event handler in order to figure out which node the user is clicking.
It turns out to be extremely slow when mounting this component, profiling result shows that EventPluginHub.putListener
consumes most of the resources.
The only solution I can think of is using jQuery to bind event handler to it's ancestor, you know, the old school way. But apparently this is against React's design philosophy.
const CategoryPicker = React.createClass({
render() {
return (
// data has about 20,000 elements
{data.map((d) => {
return (
<div onClick={this.handleClick.bind(this, d.cateId)} key={d.cateId}>
{d.cateName}
</div>
);
});}
);
}
});
Update
I've tried remove onClick
event handler on the nodes, the performance boost is evident. Guess I have to use the jQuery way to handle this situation right now.
Upvotes: 3
Views: 1904
Reputation: 365
I'm faced with code today that approached this "bubbling onClick on parent, data attributes on children" strategy everywhere. It's so painfull to read. I'd suggest using a virtual rendering system like react-table to only render the few categories visible to a user. You get a real performance boost, because you simply don't render 90% of your 20000 divs to start with. And it solves the problem of event listener with bound functions eating memory.
Upvotes: 0
Reputation: 1189
Ideally you should be attaching the event handler to a parent component (just using react, no need for jquery) and let these events bubble up. You can then use the passed event object to determine which component was clicked.
If for some reason you want to avoid this, also consider the fact the bind
itself will cause a lot of overhead. You are essentially creating a new function with every component.
Upvotes: 1