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?
One of the commonly-mentioned disadvantages of HOC is that props name of nested HOC may be conflicted, and it can be simply resolved by providing a mapper function. To better understand it, think of mapStateToProps which is used in the connect function of the familiar React-Redux Library.
The disadvantages of higher order components However there are some limitations with hoc's, here are three of them: As a user of higher order components it's not explicit what props will be added. Higher order components don't protect you from prop collision. Higher order components restrict us to static composition.
Answering those questions and building a case that higher-order components are still useful even in modern apps for certain types of tasks.
We use higher order components to primarily reuse logic in React apps. However, they have to render some UI. Hence, HOCs are inconvenient when you want to share some non-visual logic. In such a case, React hooks seem to be a perfect mechanism for code reuse.
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".
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
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With