Table of Contents

React - Children Element

About

When you create an element, you pass one or more children elements that will build the React DOM tree.

Because component are user-defined element, it applies also when you create a component.

Related: See also React - Composite Component (Layout) / Container Component

Jsx

The below example codes are created with JSX.

You may use pure javascript with the createElement function to create a element but this is not the common case.

Literal and array

Children element can be added in Jsx:

Demo:

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}
function App() {
  
  // Array of JSX
  let children = [];
  children.push(<Welcome name="Foo" key="1"/>);
  children.push(<Welcome name="Bar" key="2"/>);
  
  return (
    <div> {/* Components must return a single root element. This is the why of the ''<div>'' (to contains all the Welcome elements) */}
      <Welcome name="World" /> {/* Literal */}
      {children}
    </div>
  );
}

Passing children components via props

Components can be passed:

props.children

props.children pass all Children Components.

Some components don't know their children ahead of time.

This is especially common for components that represent generic “boxes” like:

Such components must use the special children prop to pass children elements directly into their output.

function FancyBorder(props) {
  return (
    <div className={'FancyBorder FancyBorder-' + props.color}>
      {props.children}
    </div>
  );
}
function WelcomeDialog() {
  return (
    <FancyBorder color="blue">
      <h1 className="Dialog-title">
        Welcome
      </h1>
      <p className="Dialog-message">
        Thank you for stopping by !
      </p>
    </FancyBorder>
  );
}

named props properties

Because jsx are just expression, you can pass as many component as you wish in other property of the props object.

The below example shows how to create a two panes components and to fill it with two Jsx children components that are stored in:

of the props object

Demo:

function SplitPane(props) {
  return (
    <div className="SplitPane">
      <div className="SplitPane-left">
        {props.left}
      </div>
      <div className="SplitPane-right">
        {props.right}
      </div>
    </div>
  );
}
// A left compo
function Left() {
  return <div className="Left">Left</div>;
}

// A Right compo
function Right() {
  return <div className="Right">Right</div>;
}
function App() {
  return (
    <SplitPane
      left={
        <Left />
      }
      right={
        <Right />
      } />
  );
}

Management

Child Modification

Parent components can modify a child:

Requiring Single Child

With PropTypes.element of the prop-type library, you can specify that only a single child can be passed to a component as children.

import PropTypes from 'prop-types';

class MyComponent extends React.Component {
  render() {
    // This must be exactly one element or it will warn.
    const children = this.props.children;
    return (
      <div>
        {children}
      </div>
    );
  }
}

MyComponent.propTypes = {
  children: PropTypes.element.isRequired
};

to Array of children

1) To Array

childrenArray = React.Children.toArray(props.children)

to a single Child

To child 2) while asserting that children represent a single React element

child = React.Children.only(props.children)

Typescript

How to define the children type

Example

export default function myComponent({ children }: { children: React.ReactNode; }) {
...
}
export const ContextMenu: FunctionComponent<HTMLProps<HTMLButtonElement>> = function ({children}) {
}

Get the type for the child

To get the type completion of a React element, you can validate it with isValidElement

React.isValidElement(child)

// with clone
if (React.isValidElement(childrenArray[0])) {
   labelElement = React.cloneElement(labelElement as React.ReactElement, {className: labelElement});
}

Documentation / Reference