DEV Community

Moray Macdonald
Moray Macdonald

Posted on

Which React render callback pattern do you prefer?

I found myself with an hour to myself on Friday afternoon so thought I'd relax with a good old refactoring session to tidy up some deeper parts of our React app. Whilst digging, I found that we use a couple of different abstraction patterns when one component needs to control the rendering of another. In both cases, the parent component runs a callback function to control the rendering of the child component (hence the name - callback pattern) but I can't decide which form I prefer.

Example

In my case, the parent component was part of our authorization logic which is way to complex to reproduce here, so I've simplified things! The idea is that the (reusable) parent does some processing, generates some props, and passes those props down to the child component.

Render Prop pattern

In this case, the parent component uses a prop called render which sets the logic to render the child component:

export const RenderPropsExample = () => (
  <RenderPropParent render={props => (
    <SubComponent {...props} />
  )} />
);
Enter fullscreen mode Exit fullscreen mode

Function as a Child (FaaC)

In this case, the built-in children property of the parent element sets the logic:

export const FunctionAsChildExample = () => (
  <ChildComponent>
    {props => (
      <SubComponent {...props} />
    )}
  </ChildComponent>
);
Enter fullscreen mode Exit fullscreen mode

Which is better?

As the end result is the same for both cases, is that even the right question to ask?

Personally, I like the way the FaaC pattern uses the built-in children feature of React, but I don't like the fact that I have to redefine children to be a function that returns a ReactNode, rather than just a ReactNode.

On the other hand, the Render Prop pattern doesn't have that issue - render is a custom prop so I'm free to define it however I like. But using a prop to define my component hierarchy instead of child components feels like I'm again breaking a pretty fundamental pattern in React!

What are your thoughts on this? Have I missed a way that one is superior to the other? Or is this a pointless discussion as the end result is the same? Let me know!

Top comments (0)