Rendering Children in React

06 Feb 2019

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