DEV Community

Jose Javier Señaris
Jose Javier Señaris

Posted on • Originally published at Medium on

A tale of Higher-Order Components & Render Props

In the past few months there has been an endless debate in the react community on Higher-Order Components vs. Render Props as techniques for sharing concerns and reusing common logic among components. There are tons of tutorials and courses explaining their benefits and drawbacks. Just in case you haven’t seen any of those resources, head over to the React docs which have a short and focused introduction to both terms.

Here at Ingenious we have our fair share of React Projects, of all sizes, among various teams. So far we’ve been using Higher-Order Components (HOC for short) mainly through libraries like recompose for implementing our own “Reuse this logic” component or as direct clients of popular libraries like react-redux whose main features are exposed via HOC. Just a few days ago we had the opportunity of “joining” the debate and choose one of the two approaches to implementing a new feature. The story goes like this.

We built a product where users need to leave recommendations to other users, and each recommendation can have a list of comments. Think of “Judges” that provide advice to “Participants” of a contest where anyone, be it a Judge or Participant, can give feedback multiple times on a given Recommendation.

We went all in and proposed a beautiful UI that looks similar to this:

Recommendations with nested comments

Everything went smoothly, client was happy and end of blog post.


Actually, at some point, the client requested that both Recommendations and their Comments should be editable within the first 10 minutes of being created. The final intended set of actions a user can perform with Recommendations and Comments were quite different, but the Edit workflow was pretty much the same for both entities. We wanted to make the edition similar to what users already know, which meant reusing as much as possible the UI we already had. The goal now was to add a way of selecting a recommendation or comment, fill the same input used to create it, and save the modification.

We started with Comments and built a HOC to allow editing them. Fast forwarding in time, after refactoring the common bits, we ended up with a component that allowed us to use the same logic to create/edit both Recommendations and Comments. Something like this:

By wrapping the Recommendations and Comments listings with editRecentEntity, we only need to toggle the edition mode in both entities and problem solved :-)

The Edit/Create links toggle the Edition mode for either Recommendations or Comments


A few days later another client request arrived. Now we needed to show “archived” Recommendations, which are read-only entries with more than three months old, and present a Loading indicator instead of the input form while the more recent “active” Recommendations are being retrieved from the server.

Up to this point we simply rendered a list of Recommendations followed by a Form component, all wrapped up with the editRecentEntity HOC. The Comments listing used the same pattern as well.

Hiding the forms for the archived entries has a straightforward solution, the problem then was that adding more code to show a Loading Spinner, instead of the Form, seems a bit clumsy given that it was only necessary for one type of Recommendations.

A clean solution here, was to move the responsibility of when and how to show the form, to the parent component by using the special React children prop. This idea combined with the Render Props pattern allowed to pass the necessary props to the form, so we can continue to support the creation and edition of Recommendations.

Render Props to the rescue…

Here the Render Props pattern provides an explicit API for communication between Parent and Children components. All three properties, passed to the form, depends on the logic already implemented in editRecentEntity and at the same time the “marvelous” Loading component can be used only where and how it’s needed. Go and play with the final code if that’s your thing.

The main lesson here, at least the one we learned building this feature, is that what matters most is solving the problem at hand without taking sides on hype-oriented battles of which pattern is better than the other. If the client would have stopped with the Create/Edit functionality, our code will be as worthy as the final version. Be it Higher-Order Components or Render Props, always try to choose whatever pattern, tool, library helps you solve the problem as clear as possible.

That’s all folks… Happy Coding.


PS: If you liked, or even better, disliked what you read here please drops us a line. We love to talk about technology and are always looking for awesome people that enjoy learning with and teaching us how to solve people problems.

Discussion (8)

Collapse
cutiko profile image
Erick Navarro • Edited on

The root problem is Javascript development culture, using libraries for everything halts down the problem solution proccess

Collapse
pepesenaris profile image
Jose Javier Señaris Author

I kind of agree.. Libraries per se are not the problem. They are there to solve a pain point in most cases. The problem, IMHO, comes when when we try to use a library or idea just because it's trendy without checking first if it fits our current domain.

Collapse
cutiko profile image
Erick Navarro

Sure, react-redux by example is a great implementation of the suscribe-publish pattern. However abussing libraries is prior to become a library fanboy. Recently saw a video of someone adding lodash to calculate 1 time an average. That is not using the most importanr skill in dev, solving problems. Lodash could be usefull in any project with several instace of use, but importing it for only 1 case of use?

Collapse
jcouls29 profile image
Jcouls29

Completely agree with this comment. We lose some of the basics of development when we so strongly depend on libraries and frameworks.

Collapse
lobo_tuerto profile image
Víctor Adrián

Wouldn't going with Render Props from the beginning allow you to model the 3 use cases just as smoothly?

(Sorry if this is a silly question, I don't know React).

Collapse
pepesenaris profile image
Jose Javier Señaris Author

No silly questions. Sure it will be possible. The point here is that several developers worked on the feature step by step. Each choose what it seems a good enough solution at the time and the code evolved slowly from one pattern to the other. The main take away here is to not freeze development by not deciding which pattern to use

Collapse
lobo_tuerto profile image
Víctor Adrián

Got it, thanks for the reply!

Now, if you had to do it all over again, would you still contemplate HoCs or with the newly found experience would you go directly to Render Props?

Thread Thread
pepesenaris profile image
Jose Javier Señaris Author

Probably, having all this requirements first hand, I would go with render props. Only to use the same style and for mere personal taste.