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 (<RedOrBluered={<Red />}blue={<Blue />}/>)}