How Do You Pass Props to `{this.props.children}`?

Naveera A.

The Problem

You have a parent component that acts as a wrapper around other components. Can it pass props to its children?

Let’s say we have a component called RadioGroup that has a number of children components called RadioInput, like so:

<RadioGroup> <RadioInput value="first">First</RadioInput> <RadioInput value="second">Second</RadioInput> <RadioInput value="third">Third</RadioInput> </RadioGroup>

The RadioInput component just renders an <input> element:

const RadioInput = (props) => { return ( <div> <label> {props.children} <input type="radio" name={props.name} value={props.value} /> </label> </div> ); };

To group input elements together, they must have the same name attribute. We can do it manually, like this:

<RadioGroup> <RadioInput name="group1" value="first">First</RadioInput> <RadioInput name="group1" value="second">Second</RadioInput> <RadioInput name="group1" value="third">Third</RadioInput> </RadioGroup>

But is there a way to add the name attribute programmatically by passing it as a prop to the parent component? For example:

<RadioGroup name="group1"> <RadioInput value="first">First</RadioInput> <RadioInput value="second">Second</RadioInput> <RadioInput value="third">Third</RadioInput> </RadioGroup>

The Solution

To pass additional props to the children from within the parent component, you need to clone the children components using React.cloneElement().

The React.cloneElement() API clones an element and returns a new React element. The cool thing is that the resulting element will have all of the original element’s props, with the new props merged in.

For example:

const newElement = React.cloneElement(originalElement, { extraProp: "Some extra prop", });

Here, newElement will have all the props from the originalElement, along with the extraProp.

In our original example, let’s say we have the RadioGroup component defined as follows:

const RadioGroup = (props) => { return <div>{props.children}</div>; };

You can write a function renderChildren and use it inside the return statement:

const RadioGroup = (props) => { const renderChildren = () => { return props.children; }; return <div>{renderChildren()}</div>; };

Now you can loop over all props.children using the map function and clone each child with React.cloneElement(). While cloning we will add name to the existing props, like so:

const RadioGroup = (props) => { const renderChildren = () => { return React.Children.map(props.children, (child) => { return React.cloneElement(child, { name: props.name, }); }); }; return <div>{renderChildren()}</div>; };

This way all the children components will have the name attribute set to whatever you pass to the RadioGroup component.

Get Started With Sentry

Get actionable, code-level insights to resolve React performance bottlenecks and errors.

  1. Create a free Sentry account

  2. Create a React project and note your DSN

  3. Grab the Sentry React SDK

npm install @sentry/react
  1. Configure your DSN
import React from "react"; import ReactDOM from "react-dom"; import * as Sentry from "@sentry/react"; import App from "./App"; Sentry.init({ dsn: "https://<key>@sentry.io/<project>" }); ReactDOM.render(<App />, document.getElementById("root"));

Check our documentation for the latest instructions.

Loved by over 4 million developers and more than 90,000 organizations worldwide, Sentry provides code-level observability to many of the world’s best-known companies like Disney, Peloton, Cloudflare, Eventbrite, Slack, Supercell, and Rockstar Games. Each month we process billions of exceptions from the most popular products on the internet.

Share on Twitter
Bookmark this page
Ask a questionJoin the discussion

Related Answers

A better experience for your users. An easier life for your developers.

    TwitterGitHubDribbbleLinkedinDiscord
© 2024 • Sentry is a registered Trademark
of Functional Software, Inc.