Hey everybody! This time I’m going to tell you about this great superpower called “render props”.
The term “render prop” refers to a technique for sharing code between React components using a prop whose value is a function.
The concept involved is also known as “children as a function” or “child as a function”. The components that implement this pattern can be called “render prop components”.
This is one of the advanced patterns in React that is a must to master in your daily life as a programmer.
Let’s get started:
What do we have here 👆? Let’s decode!
We have a component that receives children as a prop (it destructures it from props) and returns it as a function, with arguments. Here, children are returned with the integer 30.
Just to make sure we are on the same page, the code above is the same as writing:
Or in a more elaborated class Component:
OK! Let’s get back to where we were coming from.
To invoke this component we write a function as children:
Okay, let’s improve the code a bit.
I always use a little bit of bootstrap styling to make my examples simple, clean and a little bit polished.
Keep in mind that children are whatever exists inside the <Temperature> </Temperature> invocation.
The Temperature component is totally transparent about what children are, it just renders them passing 30 as an integer.
So the result we have in the browser is this:
Let’s say something about the weather! 😽
Okay! Nice feature you say!
But why is this a nice feature? Let’s keep your brain cool! 😃
We have separated the controller from the view! Now we have a component called Temperature which is able to receive temperatures from an API “far far away” and render its children, whichever they are, passing the temp value into them.
Make sure you understand this great benefit and superpower! The temperature Component doesn’t know its children in advance. It only knows that independent of the children it will render them and pass them the temperature value.
Of course we could make use of composition and encapsulate the children logic into another component, for example the ShowTemperature in Celsius.
Let’s do it.
And that’s it! Why is this kewl? Because now I’m going to reuse the same thingies and do a ShowTemperatureInFahrenheit!
Yeah! That’s so nice! We’ve encapsulated the render stuff into components using composition. We could keep going making a new ShowTemperature component to be invoked inside ShowTemperatureInCelsius or ShowTemperatureInFahrenheit.
But if we want to apply the render props pattern again to show different colors that we get from user preferences, for example?
Let’s try it.
Okay mates, this is a great tool but… “With great power comes great responsibility”.
If we do one or two more render prop components we’ll deep dive into a callback hell sooner than we might expect!
When we need to extract something or get some other props that come mixed in in the React cascade flow, we’re going to start to get confused and the code will become messy and not explicit or declarative anymore.
So…how can we avoid this?
Well… maybe you already thought of this. Render props is very similar in purpose to HOC (Higher Order Components).
Actually, we can use one or the other for almost the same purpose. A lot of ink has already been spent on that subject.
If you don’t know anything about HOCs, you can read my article about the container pattern here where I show you how to do a simple HOC.
I promise to write an article about HOCs in the nearly future, because it’s also a pattern that deserves some attention.
So, just as a test let’s evolve our Color abstraction to a HOC:
This is kind of a silly example but I think it helps point out the difference between these two patterns.
So… when should you use the former or the latter?
Well, everything comes with a cost. I’d dare say that I find HOC to be much cleaner than render props.
The problem is that HOCs cut the composition flow a little that makes React so great. Also in some circumstances they aren’t so performant and they tend to trigger more renders in your components — so beware of this caveat.
As a rule of thumb, I usually try to use render props because it’s a win-win pattern that prioritises composition.
If you find that you’re falling into a callback hell, then switch to HOC as a second step.
If you know, for instance, React Router, you easily have the feeling why withRouter is an HOC and <Switch/> or <Router/> are render props components. It depends a lot in which context you’re working and how you want the code to be expressive and fluid.
If you don’t know React Router, keep everything I told you in mind. Then, while you’re writing some code, try these patterns until you decide easily which is better according to the context or objective.
Last but not least, you can play a little bit around with the code in my GitHub repo here.
And that’s it everybody! 😘 😘 I hope you’ve enjoyed this small introduction to render props. For more information please check the Bibliography below!
Thank you very much!
evedes, Nov 2018