Component containment

Here we let a component render any number of child components dynamically, without knowing what they are in advance.

This is common for a sidebar or a dialog as generic boxes of other components.

This similar to slots in other libraries, like Vue.

Use the children property

Pass child components as the content of an element, such as h1 and p below in FancyBorder:

function WelcomeDialog() {
  return (
    <FancyBorder color="blue">
      <h1 className="Dialog-title">       
        Welcome     
      </h1>
      
      <p className="Dialog-message">      
        Thank you for visiting our spacecraft!     
      </p>
    </FancyBorder>
  );
}

Then insert those components within the component with the special children property:

function FancyBorder(props) {
  return (
    <div className={ `FancyBorder FancyBorder-${props.color}` }>
      { props.children }    
    </div>
  );
}

Use custom childen

Here is an alternative approach from the docs, using custom names for left and right components.

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

function App() {
  return (
    <SplitPane
      left={ <Contacts /> }
      right={ <Chat /> } 
    />
  );
}

Component specialization

See Composition vs Inheritance tutorial.

Sometimes we think about components as being “special cases” of other components.

For example, we might say that a WelcomeDialog is a special case of Dialog.

We achieve this with composition, where a specific component passes props to a generic one and renders it. This is preferred over using inheritance.

If you have common non-UI logic to be used across components, that is probably best in a plain JS module which exports functions for use in components.

Generic component:

function Dialog(props) {
  return (
    <FancyBorder color="blue">
      <h1 className="Dialog-title">
        { props.title }    
      </h1>
        
      <p className="Dialog-message">
        { props.message }    
      </p>
    </FancyBorder>
  );
}

Specialized component with values set and passed down.

function WelcomeDialog() {
  const title = "Welcome"
  const message = "Hello, React developer"
  
  return <Dialog title={ title } message={ message } />;
  
  // OR
  return <Dialog title="Welcome" message="Hello, React developer" />;
}