Reputation: 2007
Let's suppose that
List
component that iterates through a list of 10 posts and calls the Post
component for each one. Post
component using React Router's withRouter
higher-order component:For example:
const List = ({posts}) => {
return <div>{posts.map(post => <Post post={post} />)}<div>
}
There are two possible patterns:
Post
with withRouter
.List
with withRouter
and pass Router
as a prop to Post
.The first approach makes more sense logically (withRouter
lives together with the component that uses its prop) but results in 10 withRouter
wrappers in your virtual DOM.
Are there any downsides to this? Maybe from a performance standpoint? Or is it fine?
Upvotes: 7
Views: 3158
Reputation: 471
In short: using higher orders components as-is may cause you to hit performance issues sooner, so you would have to do a bit of extra work to optimize for performance when you hit these problems.
The downside to your first option is that you would instantiate an extra component instance for every list item. Depending on the length of your list you would hit performance issues sooner. So what you want to do is reduce the number of component instances but not give up on the compasability HoC's give you.
Now Andrew Clark has given a great talk about HoC's and how he built Recompose which provides utilities to "squash" HoC's with their child components, reducing the number of component instances and improve performance. As he mentions, squashing is possible if you are using functional components and if they don't access "context".
Upvotes: 3
Reputation: 571
I don't have any benchmarks to cite, but there was a really great talk about performance and React by Steve McGuire. https://youtu.be/5sETJs2_jwo?t=15m55s. I'd recommend watching the whole video, as he talks a lot about HOCs and performance in the context of super low-powered devices. The takeaway here is that they have extremely high performance goals on very constrained devices and are still using plenty of HOCs. Unless you are rendering very large datasets, or doing something where you're triggering way too many renders, you should be fine to wrap each Post
in withRouter
.
Upvotes: 2