useEffect.dev
← Back to lessons

Lesson 13. From render-props and high-order components to hooks 1. Render-props components to hooks

A render-props components is a component that accepts as child only a function, instead of classic JSX elements. For instance, here is how you can use such a component:

<RenderPropsComponent>
{(title, content) => (
<div>
<h1>{title}</h1>
<p>{content}</p>
</div>
)}
</RenderPropsComponent>

For this component to work, it must assume that the children prop it receives is a function. It can then call this function to render the returned value.

const RenderPropsComponent = ({ children }) => {
if (typeof children !== 'function') {
throw new Error('This component must receive a function as only child.')
}
// ... Fetch title and content
return children(title, content)
}

Here we only call the children function and return the result. Of course we could also integrate the result in some other tags, but render-props components are mostly used to separate a behavior from the rendering process.

As an example, let’s consider this render-props component. Its role is to fetch a post from Reddit, and pass as the child function its title and its number of upvotes.

Result

The question is now: how can I convert this render-props components to hooks? If you look at the code of the FetchRedditStory component, you will notice that it is already very close to what we would have done with a hook:

  • we declare a local state,
  • we trigger an effect, updating this state,
  • we return the result, here by calling the children function.

When you notice that, making a hook with the same behavior is straightforward: it consists in changing the last step to return the values directly instead of calling a children function.

Result

To be fair, it is not very likely you encounter such a render-props components using hooks. Most of the time, these render-props components are class-components: before hooks, there point was often to extract the “non-function” part of a component, so this component can be declared as a function.

If you want to convert a “class-render-props” component to a hook, first convert it to a function component using hooks (see Lesson 2), then convert it to a custom hook.