Rendering Children in React
There are a number of different ways to render child elements in React, and when it comes to component design, some solutions are more flexible than others. Let’s look at a few options.
Array or object prop
Flexibility: 🧘♂️
Using an array
or object
prop to render child elements is the least flexible option because the component itself controls the type of children that are rendered and their props. This approach might be suitable for components that prioritize consistency over flexibility because the component controls all aspects of rendering.
Here the component is saying: Just give me the data — I’ll take care of rendering the children.
See the Pen React Child Composition Methods - Array Prop by Peter Hrynkow (@peterhry) on CodePen.
In this example, the consumer provides an array of items and the Tabs
component decides what to render. This makes it difficult for the consumer to override the appearance and behavior of the tabs.
Children Prop
Flexibility: 🧘♂️ 🧘♂️
Using the children
prop to compose child elements is idiomatic in React. This approach is a bit more flexible because it allows the consumer to decide how to render the children. However, the result is a tight coupling between the component and its children. In order for the component to control its children, they must expose the necessary props.
Here the component is saying: Give me the children and I’ll slot them in somewhere. Just make sure they expose the required props so I can set them.
See the Pen React Child Composition Methods - Children Prop by Peter Hrynkow (@peterhry) on CodePen.
In this example, the consumer wants to use FancyTab
components instead of Tab
components. This works because FancyTab
exposes the required props selected
and onClick
.
Render Prop
Flexibility: 🧘♂️ 🧘♂️ 🧘♂️
Using a render prop to compose child elements is an advanced pattern that delegates all aspects of rendering to the consumer. Furthermore, it results in a loose coupling between the component and its children, allowing the consumer to render children with an otherwise incompatible API.
Here the component is saying: Render the children when I call this function. I’ll expose an API to help you integrate your super-custom child components.
See the Pen React Child Composition Methods - Render Prop by Peter Hrynkow (@peterhry) on CodePen.
In this example, the consumer wants to use custom HoverTab
components, but there’s one problem: The HoverTab
component exposes an onMouseEnter
prop instead of onClick
and an active
prop instead of selected
. The consumer needs a way to adapt one API to another. This is where render props come in handy.
When the Tabs
component is rendering, it invokes the children
prop (now a function) and passes it selectedIndex
and setSelectedIndex
. This allows the consumer to map the HoverTab
props to the API provided by the Tabs
component.
See also: Inversion of Control
Which approach is best?
It depends whether your component prioritizes consistency or flexibility. If you want to lock-down the design and behaviour of your component then an array
prop might be best. If you want to provide the consumer with ultimate flexibility, then go for a render prop.
Discuss on Twitter • Edit on GitHub
Keep Reading
- Why Use a JavaScript Framework
13 Jul 2019 - Rendering Children in React
06 Feb 2019 - Hacking Image Interpolation for Fun and Profit
13 Jan 2019 - The Perils of Jest Snapshot Testing
07 Jan 2019 - A Better Way to Test Your React-Redux App
01 Jan 2019 - Firebase + Create React App
01 Aug 2018 - Partial Application in Action
29 Sep 2017 - Using SVG to Shrink Your PNGs
07 Sep 2014 - Adaptive Content
06 Feb 2013