Join Kent for a live workshop in Goa, India 🇮🇳

Advanced React APIs
Time's up. The sale is over
This blog post is archived. It's no longer maintained and may contain outdated information.

When to NOT use Render Props

March 26th, 2018 — 6 min read

by Erwan Hesry
by Erwan Hesry
No translations available.Add translation

This post is only kept around for historical purposes. If you can use react@16.8.0 then the answer is to rarely use render props and almost always use a custom hook. Hooks are almost always the superior approach. Read about when you might still use render props

With all the tweets, posts, and training videos I have about the render prop pattern, I get this question a lot: "When should I not use the render props pattern?"

Every abstraction comes with a cost, even render props. But we use abstractions because we perceive the benefit outweighs the cost (or because the thought lords told us to and we didn't stop to think about it... but I digress). So when you're considering implementing a particular tool, library, or pattern, it's very important to think critically about the costs and benefits (just like we should think critically about how we manage state in our apps). To understand the benefits in this context (😉), you have to understand the problems it solves, how it goes about solving those problems (especially when compared to alternatives), and (most importantly) whether you have those problems to begin with. If you don't have the problem, then you're incurring the cost of abstraction without reaping the benefits!

The problem

So what problem does render props solve? Fundamentally, render props solves the problem of react component logic code reuse and it solves it in a way that is objectively superior to any other pattern currently. It's objectively superior because it provides more flexibility than alternatives. It can provide this flexibility because it is basically free of opinions. It allows you to bundle up your component logic into the declarative model react provides for us, and leaves you to be responsible what to do with that information. Normally this means rendering some specific UI based on some state, but it doesn't have to. React components don't have to render UI or anything at all. React components are about much more than just visual UI (consider React Router as a prime example). For more on this, watch Never Write Another HoC by Michael Jackson.

Another problem that render props have solved for me in my codebases is abstracting away imperative code. I love the example Ryan Florence gave in his talk almost 2 years ago at React Rallycalled ‹Rethinker stop={false}/› where he refactored a bunch of imperative code in a React Component's lifecycle methods to a separate <Tone /> component that abstracted away that imperative code and provided a clean declarative API instead. By doing this, Ryan made the code easier to understand because the visual UI was separated from the DOM APIs that were used to create the sound.

Note: In Ryan's example he didn't actually use a render prop (he rendered null), but we can do the same thing he did in that example with our own code. Find good examples of components that do this in the react-fns source code (by Jared Palmer and other contributors).

When to use render props:

So when do I use render props? I use them when I want to reuse component logic and when I want to abstract away imperative code to provide a easier to understand declarative API. So I use render props all the time! Not in every component, but definitely when I find myself in one of those two situations.

When to use an alternative pattern?

Never. I'm only partially kidding. There are definitely some situations where another pattern could provide a cleaner interface for regular users. Take react-redux for example. The connect higher order component is pretty straightforward and wouldn't be made much more simple by turning it into a render prop component instead. One nice thing about render props is that they give you dynamic composition, but the connect HOC solves that problem by exposing an API for the parts you'd want to have dynamic anyway (like mapStateToProps and mapPropsToDispatch).

That said, I would still use a render prop to create these higher order components. As I said earlier, render props are objectively superior pattern. But they're not always the most ergonomic. So while I would expose a connect HOC for integrating with redux like react-redux does, I would implement it using a render prop (let me show you how)! This is possible because of the power of the render prop pattern.

In combination with HOCs, the Provider pattern can also be really handy, and can also be implemented via render props (in fact, that's basically what the new context API is all about). Just for fun one day, I decided to implement a provider and HOC for downshift. It didn't take me very much time at all before I had a working implementation! This example highlights one of the reasons I prefer render props over other patterns. With render props you don't need to make and name so many useless components! But some people really enjoy breaking things out into smaller components, so it's nice to have something like this for those folks. If the HOCs fall short, people can always fall back to the regular render prop.

So here's my rule: If I want to reuse component logic or abstract away imperative code, I always start with a render prop, then if needed I'll use that component to implement common-case components to make it more usable. Common case users can use the common-case components, and advanced users can use the render prop component. Everyone wins!

Note: If you want to see more examples of how to implement a higher order component using a render prop component, check out every HOC in react-fns which do exactly that (like the withGeoPosition HOC)!

I hope that's helpful to you! Good luck!

Epic React

Get Really Good at React

Illustration of a Rocket
Kent C. Dodds
Written by Kent C. Dodds

Kent C. Dodds is a JavaScript software engineer and teacher. Kent's taught hundreds of thousands of people how to make the world a better place with quality software development tools and practices. He lives with his wife and four kids in Utah.

Learn more about Kent

Want to learn more?

Join Kent in a live workshop

If you found this article helpful.

You will love these ones as well.