Advanced React

Composition Components

Besides High Order Components, React also has a powerful composition model which enables you to reuse code between components


Containment

Some components don’t know their children ahead of time. This is especially common for components like Sidebar or Modal that represent generic “boxes”.

We recommend that such components use the special children prop to pass children elements directly into their output:

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

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

Anything inside the <Modal> JSX tag gets passed into the Modal component as a children prop. You can also pass a component to another one as a prop. Check the example below

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 />
      } />
  );
}

Specialization

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

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

function WelcomeDialog() {
  return (
    <Dialog
      title="Welcome"
      message="Thank you for visiting our spacecraft!" />
  );
}

Another example

() => {
function Red() {
return (
<div style={{ width: 40, height: 40, background: 'red' }} />
)
}
function Blue() {
return (
<div style={{ width: 40, height: 40, background: 'blue' }} />
)
}
function RedOrBlue(props) {
const [color, setColor] = useState('red')
const handleChangeColor = () => {
setColor(c => c === 'red' ? 'blue' : 'red')
}
return (
<div>
{props[color]}
<Button onClick={handleChangeColor}>Change Color</Button>
</div>
)
}
return (
<RedOrBlue
red={<Red />}
blue={<Blue />}
/>
)
}
Previous
Callback Hell and Async