Состав против наследования
В React имеется мощная модель композиции, и мы рекомендуем использовать композицию вместо наследования для повторного использования кода между компонентами.
В этом разделе мы рассмотрим несколько проблем, с которыми разработчики, не знакомые с React, часто тянутся к наследованию, и покажем, как их можно решить с помощью композиции.
политика сдерживания
Некоторые компоненты не знают своих детей раньше времени. Это особенно характерно для таких компонентов, как боковая панель или диалог, которые представляют общие «блоки».
Мы рекомендуем, чтобы такие компоненты использовали специальную дочернюю опору для передачи дочерних элементов непосредственно в их вывод:
function FancyBorder(props) {
return (
<div className={'FancyBorder FancyBorder-' + props.color}>
{props.children}
</div>
);
}
Это позволяет другим компонентам передавать им произвольные дочерние элементы путем вложения JSX:
function WelcomeDialog() {
return (
<FancyBorder color="blue">
<h1 className="Dialog-title">
Welcome
</h1>
<p className="Dialog-message">
Thank you for visiting our spacecraft!
</p>
</FancyBorder>
);
}
Все, что находится внутри тега <FancyBorder> JSX, передается в компонент FancyBorder как дочерний объект. Поскольку FancyBorder отображает {props.children} внутри <div>, переданные элементы появляются в конечном выводе.
Хотя это не так часто, иногда вам может понадобиться несколько «дырок» в компоненте. В таких случаях вы можете придумать свое собственное соглашение вместо использования детей:
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 />
} />
);
}
Элементы React, такие как <Contacts /> и <Chat />, являются просто объектами, поэтому вы можете передавать их как реквизиты, как и любые другие данные. Такой подход может напомнить вам о «слотах» в других библиотеках, но нет никаких ограничений на то, что вы можете передавать как реквизиты в React.
специализация
Иногда мы думаем о компонентах как о «особых случаях» других компонентов. Например, мы можем сказать, что WelcomeDialog - это особый случай Dialog.
В React это также достигается композицией, где более «конкретный» компонент отображает более «общий» компонент и настраивает его с помощью реквизитов:
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!" />
);
}
Композиция работает одинаково хорошо для компонентов, определенных как классы:
function Dialog(props) {
return (
<FancyBorder color="blue">
<h1 className="Dialog-title">
{props.title}
</h1>
<p className="Dialog-message">
{props.message}
</p>
{props.children}
</FancyBorder>
);
}
class SignUpDialog extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
this.handleSignUp = this.handleSignUp.bind(this);
this.state = {login: ''};
}
render() {
return (
<Dialog title="Mars Exploration Program"
message="How should we refer to you?">
<input value={this.state.login}
onChange={this.handleChange} />
<button onClick={this.handleSignUp}>
Sign Me Up!
</button>
</Dialog>
);
}
handleChange(e) {
this.setState({login: e.target.value});
}
handleSignUp() {
alert(`Welcome aboard, ${this.state.login}!`);
}
}
Новый контент: Composer: менеджер зависимостей для PHP , R программирования