React Custom Hooks and the death of Render Props
Tags: web, webdev, hooks, tech
Published: 2018-12-18 15:55:37

---
title: React Custom Hooks and the death of Render Props
published: true
tags: web,web-development,hooks,tech
canonical_url: https://blog.logrocket.com/react-custom-hooks-and-the-death-of-render-props-a0ce5cba387f
---

#### Everyone had something to say about React Hooks when it was introduced last month. But I didn’t see anyone say we can stop using Render Props. So I’ll say it. We can stop using Render Props. In this article, we’ll learn how to do just that.

![](https://cdn-images-1.medium.com/max/1024/1*cN7WiJ3nIuETV69OXbKFdQ.jpeg)

**Note ** — Render Props won’t _completely_ die off but they will not be used for what we are currently accustomed to. Also, React Hooks **are still in alpha** so it is **not recommended to use them in production**. Please don’t rush to refactor all your existing applications.

[![](https://cdn-images-1.medium.com/max/1024/1*GPjaPKNNUYHU8EsA3Z0JGA.png)](https://logrocket.com/signup/)

### What are Render Props?

**Render Props** are an advanced pattern for sharing logic across components. A component (usually termed as Container Component) can delegate how the UI looks to other components (called Presentation Components) and only implement the business logic itself. So we can implement cross-cutting concerns as components by using Render Props pattern.

### Why do we need Render Props?

1. For sharing code between components
2. To use the Context API

### The problem with Render Props

Using Render Props comes with its own issues. Some of these issues appear only when we dig deeper or when we scale our project.

#### Wrapper Hell

To increase the DRYness of our codebase we often implement many small, granular components such that each component deals with only one concern. The issue with that is we are often left with a whole lot of wrapper components nested deeply inside one another. If we decrease the number of wrapper components then the component size and complexity increases. **Also, the reusability of a wrapper component might decrease too.** This tweet perfectly sums it up.

<style>body[data-twttr-rendered="true"] {background-color: transparent;}.twitter-tweet {margin: auto !important;}</style>

> [@threepointone](http://twitter.com/threepointone "Twitter profile for @threepointone") [@kentcdodds](http://twitter.com/kentcdodds "Twitter profile for @kentcdodds") I mean come on (screen shot of actual code I'm playing with right now)
> 
>  — [@acdlite](https://twitter.com/acdlite/status/955955121979969537)

<script src="//platform.twitter.com/widgets.js" charset="utf-8"></script><script>function notifyResize(height) {height = height ? height : document.documentElement.offsetHeight; var resized = false; if (window.donkey && donkey.resize) {donkey.resize(height); resized = true;}if (parent && parent._resizeIframe) {var obj = {iframe: window.frameElement, height: height}; parent._resizeIframe(obj); resized = true;}if (window.location && window.location.hash === "#amp=1" && window.parent && window.parent.postMessage) {window.parent.postMessage({sentinel: "amp", type: "embed-size", height: height}, "*");}if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.resize) {window.webkit.messageHandlers.resize.postMessage(height); resized = true;}return resized;}twttr.events.bind('rendered', function (event) {notifyResize();}); twttr.events.bind('resize', function (event) {notifyResize();});</script><script>if (parent && parent._resizeIframe) {var maxWidth = parseInt(window.frameElement.getAttribute("width")); if ( 500 < maxWidth) {window.frameElement.setAttribute("width", "500");}}</script>
#### Binding `this` is a pain

Since the wrapper components deal with state or lifecycle methods, they have to use Class Components. With Class Components we have to bind this properly otherwise we risk losing the this context inside functions. The syntax for binding all methods looks ugly and is a burden for developers.

#### Classes are hard for humans as well as machines

Classes come with a good amount of boilerplate code which is awful for us to write every time we convert a functional component into a class component. Turns out, classes are hard to optimize by our build tools also. This incurs a double penalty because it neither leads to good DX (developer experience) nor good UX (user experience). React team is even thinking of moving Class Components support to a separate package in the future.

#### Using PureComponent becomes complicated

Using a render prop can negate the advantage that comes from using PureComponent if we create the function assigned inside the render method. This is because the **shallow prop comparison will always return false for new props** , and each render, in this case, will generate a new value for the render prop. Refer to the [docs](https://reactjs.org/docs/render-props.html#be-careful-when-using-render-props-with-reactpurecomponent) for more details.

Many of these problems are not entirely the fault of the Render Props pattern though. Until now, React did not provide a way of using state or lifecycle methods without involving classes and that’s why we had to use classes in container components for implementing Render Props pattern.

However, all of that changes with the introduction of the React Hooks API. React Hooks lets us use state and lifecycle hooks inside functional components with only a few lines of codes.

<style>body[data-twttr-rendered="true"] {background-color: transparent;}.twitter-tweet {margin: auto !important;}</style>

> [@ericandrewlewis](http://twitter.com/ericandrewlewis "Twitter profile for @ericandrewlewis") [@ReactPodcast](http://twitter.com/ReactPodcast "Twitter profile for @ReactPodcast") [@dan\_abramov](http://twitter.com/dan_abramov "Twitter profile for @dan\_abramov") [@jaredpalmer](http://twitter.com/jaredpalmer "Twitter profile for @jaredpalmer") between Suspense (anything that needs to be scheduled) and Hooks (effects, context, and local state), there are very few remaining use cases for render props that don't have framework-level aolutions
> 
>  — [@chantastic](https://twitter.com/chantastic/status/1064916849433833473)

<script src="//platform.twitter.com/widgets.js" charset="utf-8"></script><script>function notifyResize(height) {height = height ? height : document.documentElement.offsetHeight; var resized = false; if (window.donkey && donkey.resize) {donkey.resize(height); resized = true;}if (parent && parent._resizeIframe) {var obj = {iframe: window.frameElement, height: height}; parent._resizeIframe(obj); resized = true;}if (window.location && window.location.hash === "#amp=1" && window.parent && window.parent.postMessage) {window.parent.postMessage({sentinel: "amp", type: "embed-size", height: height}, "*");}if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.resize) {window.webkit.messageHandlers.resize.postMessage(height); resized = true;}return resized;}twttr.events.bind('rendered', function (event) {notifyResize();}); twttr.events.bind('resize', function (event) {notifyResize();});</script><script>if (parent && parent._resizeIframe) {var maxWidth = parseInt(window.frameElement.getAttribute("width")); if ( 500 < maxWidth) {window.frameElement.setAttribute("width", "500");}}</script>

What’s even better is that we can implement our own Custom Hooks. These hooks give us a new, easy and powerful primitive for sharing logic across components. That means we don’t need classes or render props pattern to share code between components. Before jumping into that, let’s first get a good look at how React Hooks can be used.

### A basic example of React Hooks

The best way to learn something is by using it. So to use React Hooks, we’ll build a component which by default shows some information and lets us update that information by clicking a button. It will look something like this.

![](https://cdn-images-1.medium.com/max/622/1*nptdcTRGEt0V88W2mzfqWQ.gif)<figcaption><strong>Editable Item with React Hooks</strong> (Click <a href="http://recordit.co/fsqbCcOFSi">here</a> for video)</figcaption>

What we can observe is that the component has two types of states. One state is for [controlling](https://reactjs.org/docs/forms.html#controlled-components) the input field and the other state is to toggle between the viewer and the editor. Let’s see how this can be implemented with React Hooks.

![](https://cdn-images-1.medium.com/max/1024/1*XzG-WcpZX_nFymuQtINSfg.png)<figcaption><a href="https://carbon.now.sh/?bg=rgba(255%2C255%2C255%2C0)&amp;t=material&amp;wt=none&amp;l=jsx&amp;ds=true&amp;dsyoff=5px&amp;dsblur=34px&amp;wc=true&amp;wa=false&amp;pv=27px&amp;ph=32px&amp;ln=false&amp;fm=Hack&amp;fs=13px&amp;lh=199%25&amp;si=false&amp;code=import%2520React%252C%2520%257B%2520useState%2520%257D%2520from%2520%2522react%2522%253B%250A%250Afunction%2520EditableItem(%257B%2520label%252C%2520initialValue%2520%257D)%2520%257B%250A%2520%2520const%2520%255Bvalue%252C%2520setValue%255D%2520%253D%2520useState(initialValue)%253B%250A%2520%2520const%2520%255BeditorVisible%252C%2520setEditorVisible%255D%2520%253D%2520useState(false)%253B%250A%250A%2520%2520const%2520toggleEditor%2520%253D%2520()%2520%253D%253E%2520setEditorVisible(!editorVisible)%253B%250A%250A%2520%2520return%2520(%250A%2520%2520%2520%2520%253Cmain%253E%250A%2520%2520%2520%2520%2520%2520%257BeditorVisible%2520%253F%2520(%250A%2520%2520%2520%2520%2520%2520%2520%2520%253Clabel%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%257Blabel%257D%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%253Cinput%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520type%253D%2522text%2522%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520value%253D%257Bvalue%257D%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520onChange%253D%257Bevent%2520%253D%253E%2520setValue(event.target.value)%257D%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%252F%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%253C%252Flabel%253E%250A%2520%2520%2520%2520%2520%2520)%2520%253A%2520(%250A%2520%2520%2520%2520%2520%2520%2520%2520%253Cspan%253E%257Bvalue%257D%253C%252Fspan%253E%250A%2520%2520%2520%2520%2520%2520)%257D%250A%2520%2520%2520%2520%2520%2520%253Cbutton%2520onClick%253D%257BtoggleEditor%257D%253E%257BeditorVisible%2520%253F%2520%2522Done%2522%2520%253A%2520%2522Edit%2522%257D%253C%252Fbutton%253E%250A%2520%2520%2520%2520%253C%252Fmain%253E%250A%2520%2520)%253B%250A%257D&amp;es=4x&amp;wm=false">Link</a> to code</figcaption>

We have defined a functional component called **EditableItem** which takes two props, label and initialValue. **label** prop is for showing the label above the input field and the **initialValue** prop is for showing the default info.

Calling the **useState** hook gives us an array of two items, the first one is for reading state and the next is for updating that state. We will hold the state for controlled input in the **value** variable and the state updater function in the **setValue** variable. By default, **value** variable will be assigned the **initialValue** prop data.

Next, we hold the state for toggling between viewer and editor in the **editorVisible** variable and its updater in the **setEditorVisible** variable. In the markup, we render the viewer when the value of **editorVisible** is **false** and render the editor when the value is **true.** Since we want to show the viewer by default, we need to have **editorVisible** value as false initially. That’s why we pass **false** while calling **useState**.

To toggle between the viewer and editor we define a **toggleEditor** function which sets the **editorVisible** state to it’s opposite everytime the function is called. As we want to call this function whenever the user clicks on the button, we assign it as **onClick** prop of the button.

That’s how easy using React Hooks can be but it doesn’t stop here. Hooks have one more trick up their sleeves and that is Custom Hooks. We can see that the **editorVisible** state is actually a toggler and toggling is a very common use-case in our UIs. If we wanted to share the toggling logic across components, we would define a Toggler component and use render props pattern to share the toggling method. But wouldn’t it be easier if we could just have a function for that instead of messing with components? Enter Custom Hooks…

### Using Custom React Hooks for sharing logic between components

With Custom Hooks we can extract the toggling logic from the EditableItem component into a separate function. We will call this function **useToggle** as it is recommended to start the name of a custom hook with the word “use”. The **useToggle** custom hook will look like this:

![](https://cdn-images-1.medium.com/max/1024/1*GoJsjaaKsOa315JuR5iBiw.png)<figcaption><a href="https://carbon.now.sh/?bg=rgba(255%2C255%2C255%2C0)&amp;t=material&amp;wt=none&amp;l=jsx&amp;ds=true&amp;dsyoff=5px&amp;dsblur=34px&amp;wc=true&amp;wa=false&amp;pv=27px&amp;ph=32px&amp;ln=false&amp;fm=Hack&amp;fs=13px&amp;lh=199%25&amp;si=false&amp;code=import%2520React%252C%2520%257B%2520useState%2520%257D%2520from%2520%2522react%2522%253B%250A%250Afunction%2520useToggle(initialValue)%2520%257B%250A%2520%2520const%2520%255BtoggleValue%252C%2520setToggleValue%255D%2520%253D%2520useState(initialValue)%253B%250A%2520%2520const%2520toggler%2520%253D%2520()%2520%253D%253E%2520setToggleValue(!toggleValue)%253B%250A%250A%2520%2520return%2520%255BtoggleValue%252C%2520toggler%255D%253B%250A%257D&amp;es=4x&amp;wm=false">Link</a> to code</figcaption>

First, we get the state and state updater by using the useState hook. Then we define a **toggler** function which sets the **toggleValue** to the opposite of its current value. At last, we return an array of two items, first is **toggleValue** to read the current state and the next is **toggler** to toggle the **toggleValue** state.

Though [creating functions at each render is not slow in modern browsers](https://reactjs.org/docs/hooks-faq.html#are-hooks-slow-because-of-creating-functions-in-render) we can avoid that by memoizing the **toggler** function. For this purpose **useCallback** hook comes in handy. More details can be found [here](https://reactjs.org/docs/hooks-reference.html#usecallback).

![](https://cdn-images-1.medium.com/max/1024/1*kiRzqu5izJD724nr2dIcLw.png)<figcaption><a href="https://carbon.now.sh/?bg=rgba(255%2C255%2C255%2C0)&amp;t=material&amp;wt=none&amp;l=jsx&amp;ds=true&amp;dsyoff=5px&amp;dsblur=34px&amp;wc=true&amp;wa=false&amp;pv=27px&amp;ph=32px&amp;ln=false&amp;fm=Hack&amp;fs=13px&amp;lh=199%25&amp;si=false&amp;code=import%2520React%252C%2520%257B%2520useState%252C%2520useCallback%2520%257D%2520from%2520%2522react%2522%253B%250A%250Afunction%2520useToggle(initialValue)%2520%257B%250A%2520%2520const%2520%255BtoggleValue%252C%2520setToggleValue%255D%2520%253D%2520useState(initialValue)%253B%250A%2520%2520const%2520toggler%2520%253D%2520useCallback(()%2520%253D%253E%2520setToggleValue(!toggleValue))%253B%250A%250A%2520%2520return%2520%255BtoggleValue%252C%2520toggler%255D%253B%250A%257D&amp;es=4x&amp;wm=false">Link</a> to code</figcaption>

Custom hooks are used just like any other hook. This means using **useToggle** in our **EditableItem** component is as easy as this:

![](https://cdn-images-1.medium.com/max/1024/1*lHIMzid8rudkaYSTab1l0g.png)<figcaption><a href="https://carbon.now.sh/?bg=rgba(255%2C255%2C255%2C0)&amp;t=material&amp;wt=none&amp;l=jsx&amp;ds=true&amp;dsyoff=5px&amp;dsblur=34px&amp;wc=true&amp;wa=false&amp;pv=27px&amp;ph=32px&amp;ln=false&amp;fm=Hack&amp;fs=13px&amp;lh=199%25&amp;si=false&amp;code=import%2520React%252C%2520%257B%2520useState%2520%257D%2520from%2520%2522react%2522%253B%250A%250Aimport%2520useToggle%2520from%2520%27useToggle.js%27%253B%250A%250Afunction%2520EditableItem(%257B%2520label%252C%2520initialValue%2520%257D)%2520%257B%250A%2520%2520const%2520%255Bvalue%252C%2520setValue%255D%2520%253D%2520useState(initialValue)%253B%250A%2520%2520const%2520%255BeditorVisible%252C%2520toggleEditorVisible%255D%2520%253D%2520useToggle(false)%253B%250A%250A%2520%2520return%2520(%250A%2520%2520%2520%2520%253Cmain%253E%250A%2520%2520%2520%2520%2520%2520%257BeditorVisible%2520%253F%2520(%250A%2520%2520%2520%2520%2520%2520%2520%2520%253Clabel%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%257Blabel%257D%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%253Cinput%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520type%253D%2522text%2522%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520value%253D%257Bvalue%257D%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520onChange%253D%257Bevent%2520%253D%253E%2520setValue(event.target.value)%257D%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%252F%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%253C%252Flabel%253E%250A%2520%2520%2520%2520%2520%2520)%2520%253A%2520(%250A%2520%2520%2520%2520%2520%2520%2520%2520%253Cspan%253E%257Bvalue%257D%253C%252Fspan%253E%250A%2520%2520%2520%2520%2520%2520)%257D%250A%2520%2520%2520%2520%2520%2520%253Cbutton%2520onClick%253D%257BtoggleEditorVisible%257D%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%257BeditorVisible%2520%253F%2520%2522Done%2522%2520%253A%2520%2522Edit%2522%257D%250A%2520%2520%2520%2520%2520%2520%253C%252Fbutton%253E%250A%2520%2520%2520%2520%253C%252Fmain%253E%250A%2520%2520)%253B%250A%257D&amp;es=4x&amp;wm=false">Link</a> to code</figcaption>

Let’s see how Render Props fare in comparison to React Hooks:

<iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/3591dac4e57ed134da7735713ee17b03/href">https://medium.com/media/3591dac4e57ed134da7735713ee17b03/href</a></iframe><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ad8c63daf90a0e08713436aad3ceb74c/href">https://medium.com/media/ad8c63daf90a0e08713436aad3ceb74c/href</a></iframe>

No doubt, code reuse between components is easier with Custom Hooks and also require less amount of code. Next, we’ll learn how to consume context data with React Hooks instead of using Render Props pattern.

### Using Reacts Hooks for consuming context data

Just like we have **useState** hook for state, we have **useContext** for consuming context data. Again, we’ll try to learn it by using it in a practical scenario. Well, it’s a common requirement to have user details available across components. This is a great use-case for context hooks:

![](https://cdn-images-1.medium.com/max/759/1*uKsAkIAit5L4iuEiJzU9bg.gif)<figcaption><strong>Use Context to change user</strong> (Click <a href="http://recordit.co/VYFdKNIQos">here</a> for video)</figcaption>

Here we have two components **UserProfile** and **ChangeProfile**. **UserProfile** component shows the details of the user and the **ChangeProfile** component is used for switching between users.

**Note — ** The switching between users part is just for our demo. In real projects, instead of the select menu, we will update user details based on who logs in.

The implementation might look like this:

<iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/4a7b03b04eab8e0469bfc52b921b543a/href">https://medium.com/media/4a7b03b04eab8e0469bfc52b921b543a/href</a></iframe>

We have made a separate component called **User** for storing user state and providing data and data update method to **UserContext.Provider**. These are then consumed by its children components **UserProfile** and **ChangeProfile**. The **UserProfile** component only needs to read the user details so we only destructure the first item from the array returned by **useContext**.

The **ChangeProfile** component has an array of profiles. When the user selects one profile, we update the **UserContext** by using the **setUser** method provided by **UserContext** itself **.** This example is enough to show that using context is also very simple with Custom Hooks.

There is one more thing for which people sometimes use Render Props pattern. That is for implementing slots in their components like this:

![](https://cdn-images-1.medium.com/max/1024/1*B3iu8aZxd0Q-vF_LG60kIg.png)<figcaption><a href="https://carbon.now.sh/?bg=rgba(255%2C255%2C255%2C0)&amp;t=material&amp;wt=none&amp;l=jsx&amp;ds=true&amp;dsyoff=5px&amp;dsblur=34px&amp;wc=true&amp;wa=false&amp;pv=27px&amp;ph=32px&amp;ln=false&amp;fm=Hack&amp;fs=13px&amp;lh=199%25&amp;si=false&amp;code=function%2520Card(%257B%2520title%252C%2520body%252C%2520action%257D)%2520%257B%250A%2520%2520return%2520(%250A%2520%2520%2520%2520%253Csection%2520className%253D%27card%27%253E%250A%2520%2520%2520%2520%2520%2520%253Cnav%2520className%253D%27header%27%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%257Btitle()%257D%250A%2520%2520%2520%2520%2520%2520%253C%252Fnav%253E%250A%2520%2520%2520%2520%2520%2520%253Cmain%2520className%253D%27main%27%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%257Bbody()%257D%250A%2520%2520%2520%2520%2520%2520%253C%252Fmain%253E%250A%2520%2520%2520%2520%2520%2520%253Cfooter%2520className%253D%27footer%27%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%257Baction()%257D%250A%2520%2520%2520%2520%2520%2520%253C%252Ffooter%253E%250A%2520%2520%2520%2520%253C%252Fsection%253E%250A%2520%2520)%250A%257D%250A%250Afunction%2520App()%2520%257B%250A%2520%2520return%2520(%250A%2520%2520%2520%2520%253CCard%250A%2520%2520%2520%2520%2520%2520title%253D%257B()%2520%253D%253E%2520(%250A%2520%2520%2520%2520%2520%2520%2520%2520%253Ch2%253ECard%2520Title%253C%252Fh2%253E%250A%2520%2520%2520%2520%2520%2520)%257D%250A%2520%2520%2520%2520%2520%2520body%253D%257B()%2520%253D%253E%2520(%250A%2520%2520%2520%2520%2520%2520%2520%2520%253Cdiv%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%253Cp%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520Some%2520Content%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%253C%252Fp%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%253Ca%2520href%253D%2522%252Flink%2522%253ESome%2520Link%253C%252Fa%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%253C%252Fdiv%253E%250A%2520%2520%2520%2520%2520%2520)%257D%250A%2520%2520%2520%2520%2520%2520action%253D%257B()%2520%253D%253E%2520(%250A%2520%2520%2520%2520%2520%2520%2520%2520%253Cbutton%2520onClick%253D%257B()%2520%253D%253E%2520console.log(%27clicked%27)%257D%253ESome%2520Action%253C%252Fbutton%253E%250A%2520%2520%2520%2520%2520%2520)%257D%250A%2520%2520%2520%2520%252F%253E%250A%2520%2520)%250A%257D&amp;es=4x&amp;wm=false">Link</a> to code</figcaption>

Well, there is a simpler way, one that doesn’t need functions as props. We can just assign JSX as component props like this:

![](https://cdn-images-1.medium.com/max/1024/1*VCn33MDJhaictGUjOpheuQ.png)<figcaption><a href="https://carbon.now.sh/?bg=rgba(255%2C255%2C255%2C0)&amp;t=material&amp;wt=none&amp;l=jsx&amp;ds=true&amp;dsyoff=5px&amp;dsblur=34px&amp;wc=true&amp;wa=false&amp;pv=27px&amp;ph=32px&amp;ln=false&amp;fm=Hack&amp;fs=13px&amp;lh=199%25&amp;si=false&amp;code=function%2520Card(%257B%2520title%252C%2520body%252C%2520action%2520%257D)%2520%257B%250A%2520%2520return%2520(%250A%2520%2520%2520%2520%253Csection%2520className%253D%2522card%2522%253E%250A%2520%2520%2520%2520%2520%2520%253Cnav%2520className%253D%2522header%2522%253E%257Btitle%257D%253C%252Fnav%253E%250A%2520%2520%2520%2520%2520%2520%253Cmain%2520className%253D%2522main%2522%253E%257Bbody%257D%253C%252Fmain%253E%250A%2520%2520%2520%2520%2520%2520%253Cfooter%2520className%253D%2522footer%2522%253E%257Baction%257D%253C%252Ffooter%253E%250A%2520%2520%2520%2520%253C%252Fsection%253E%250A%2520%2520)%253B%250A%257D%250A%250Afunction%2520App()%2520%257B%250A%2520%2520return%2520(%250A%2520%2520%2520%2520%253CCard%250A%2520%2520%2520%2520%2520%2520title%253D%257B%253Ch2%253ECard%2520Title%253C%252Fh2%253E%257D%250A%2520%2520%2520%2520%2520%2520body%253D%257B%250A%2520%2520%2520%2520%2520%2520%2520%2520%253Cdiv%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%253Cp%253ESome%2520Content%253C%252Fp%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520%253Ca%2520href%253D%2522%252Flink%2522%253ESome%2520Link%253C%252Fa%253E%250A%2520%2520%2520%2520%2520%2520%2520%2520%253C%252Fdiv%253E%250A%2520%2520%2520%2520%2520%2520%257D%250A%2520%2520%2520%2520%2520%2520action%253D%257B%250A%2520%2520%2520%2520%2520%2520%2520%2520%253Cbutton%2520onClick%253D%257B()%2520%253D%253E%2520console.log(%2522clicked%2522)%257D%253ESome%2520Action%253C%252Fbutton%253E%250A%2520%2520%2520%2520%2520%2520%257D%250A%2520%2520%2520%2520%252F%253E%250A%2520%2520)%253B%250A%257D&amp;es=4x&amp;wm=false">Link</a> to code</figcaption>

Using Render Props pattern here would be a mistake because its intended use is to share data between components. So, in this case, we should avoid using Render Props.

My personal opinion is that Render Props pattern wasn’t intended for the above use cases but the community had to use it because there was no other way. It’s great that the React team took note and made something we will all love to use. Hooks and Render Props can co-exist because each has a different role. [Michael Chan](http://twitter.com/chantastic) has made a video explaining that.

<iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2F_jehVItn7Vo%3Ffeature%3Doembed&amp;url=http%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3D_jehVItn7Vo&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2F_jehVItn7Vo%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/6c3846b43caf82f8fc45379ae0d87446/href">https://medium.com/media/6c3846b43caf82f8fc45379ae0d87446/href</a></iframe>
### Conclusion

It’s clear that the future of React is very bright. The React team focus is crystal clear. If anyone knows of other use-cases for Render Props let me know, I’ll surely mention them in the article.

If you like my work, please follow me on [Twitter](https://twitter.com/dev__adi) and [Medium](https://medium.com/@adityaa803) or subscribe to [my newsletter](https://buttondown.email/itaditya).

### Plug: [LogRocket](https://logrocket.com/signup/), a DVR for web apps

[![](https://cdn-images-1.medium.com/max/1024/1*s_rMyo6NbrAsP-XtvBaXFg.png)](https://logrocket.com/signup/)<figcaption><a href="https://logrocket.com/signup/">https://logrocket.com/signup/</a></figcaption>

[LogRocket](https://logrocket.com/signup/) is a frontend logging tool that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store.

In addition to logging Redux actions and state, LogRocket records console logs, JavaScript errors, stacktraces, network requests/responses with headers + bodies, browser metadata, and custom logs. It also instruments the DOM to record the HTML and CSS on the page, recreating pixel-perfect videos of even the most complex single page apps.

[Try it for free.](https://logrocket.com/signup/)

* * *