Skip to content

Composition vs Inheritance #12

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Feb 17, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 29 additions & 29 deletions content/docs/composition-vs-inheritance.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
---
id: composition-vs-inheritance
title: Composition vs Inheritance
title: Композиція проти наслідування
permalink: docs/composition-vs-inheritance.html
redirect_from:
- "docs/multiple-components.html"
prev: lifting-state-up.html
next: thinking-in-react.html
---

React has a powerful composition model, and we recommend using composition instead of inheritance to reuse code between components.
React має потужну модель композиції і ми рекомендуємо використовувати композицію замість наслідування для повторного використання коду між компонентами.

In this section, we will consider a few problems where developers new to React often reach for inheritance, and show how we can solve them with composition.
В цьому розділі ми розглянемо кілька проблем, котрі нові React-розробники вирішують за допомогою наслідування і покажемо, як вони вирішуються за допомогою композиції.

## Containment {#containment}
## Запобіжні заходи {#containment}

Some components don't know their children ahead of time. This is especially common for components like `Sidebar` or `Dialog` that represent generic "boxes".
Деякі компоненти не знають заздалегідь про свої дочірні елементи. Це особливо характерно для таких компонентів як `Sidebar` чи `Dialog`, котрі представляють собою загальні контейнери.

We recommend that such components use the special `children` prop to pass children elements directly into their output:
Ми рекомендуємо, щоб такі компоненти використовували особливий проп `children` для передачі дочірніх елементів напряму до свого виводу:

```js{4}
function FancyBorder(props) {
Expand All @@ -28,7 +28,7 @@ function FancyBorder(props) {
}
```

This lets other components pass arbitrary children to them by nesting the JSX:
Це дозволяє іншим компонентам передавати їм довільні дочірні елементи шляхом вкладення JSX:

```js{4-9}
function WelcomeDialog() {
Expand All @@ -38,18 +38,18 @@ function WelcomeDialog() {
Welcome
</h1>
<p className="Dialog-message">
Thank you for visiting our spacecraft!
Дякуємо, що завітали на борт нашого космічного корабля!
</p>
</FancyBorder>
);
}
```

**[Try it on CodePen](https://codepen.io/gaearon/pen/ozqNOV?editors=0010)**
**[Спробувати на CodePen](https://codepen.io/gaearon/pen/ozqNOV?editors=0010)**

Anything inside the `<FancyBorder>` JSX tag gets passed into the `FancyBorder` component as a `children` prop. Since `FancyBorder` renders `{props.children}` inside a `<div>`, the passed elements appear in the final output.
Усе, що знаходиться між JSX тегом `<FancyBorder>` буде передане в `FancyBorder` компонент як `children` проп. Оскільки `FancyBorder` рендерить `{props.children}` всередині `<div>`, передані елементи з'являться у фінальному виводі.

While this is less common, sometimes you might need multiple "holes" in a component. In such cases you may come up with your own convention instead of using `children`:
Іноді, хоч і не так часто, вам може знадобитись кілька подібних "слотів" у компоненті. У таких випадках ви можети придумати власне рішення замість використання `children`:

```js{5,8,18,21}
function SplitPane(props) {
Expand Down Expand Up @@ -78,15 +78,15 @@ function App() {
}
```

[**Try it on CodePen**](https://codepen.io/gaearon/pen/gwZOJp?editors=0010)
[**Спробувати на CodePen**](https://codepen.io/gaearon/pen/gwZOJp?editors=0010)

React elements like `<Contacts />` and `<Chat />` are just objects, so you can pass them as props like any other data. This approach may remind you of "slots" in other libraries but there are no limitations on what you can pass as props in React.
Такі React-елементи як `<Contacts />` і `<Chat />` є звичайними об'єктами, а отже ви можете передати їх в ролі пропсів, як і будь-які інші дані. Такий підхід може нагадати вам "слоти" в інших бібліотеках, але React не обмежує вас у тому, що ви можете передати як пропси.

## Specialization {#specialization}
## Спеціалізація {#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`.
Іноді ми розглядаємо компоненти як "особливий випадок" інших компонентів. Наприклад, ми можемо сказати, що `WelcomeDialog` є особливим випадком `Dialog`.

In React, this is also achieved by composition, where a more "specific" component renders a more "generic" one and configures it with props:
У React подібне також досягається композицією, коли більш "конкретний" компонент рендерить більш "загальний" і налаштовує його за допомогою пропсів:

```js{5,8,16-18}
function Dialog(props) {
Expand All @@ -105,15 +105,15 @@ function Dialog(props) {
function WelcomeDialog() {
return (
<Dialog
title="Welcome"
message="Thank you for visiting our spacecraft!" />
title="Ласкаво просимо"
message="Дякуємо, що завітали на борт нашого космічного корабля!" />
);
}
```

[**Try it on CodePen**](https://codepen.io/gaearon/pen/kkEaOZ?editors=0010)
[**Спробувати на CodePen**](https://codepen.io/gaearon/pen/kkEaOZ?editors=0010)

Composition works equally well for components defined as classes:
Композиція працює так само добре для компонентів визначених як класи:

```js{10,27-31}
function Dialog(props) {
Expand All @@ -140,12 +140,12 @@ class SignUpDialog extends React.Component {

render() {
return (
<Dialog title="Mars Exploration Program"
message="How should we refer to you?">
<Dialog title="Програма дослідження Марсу"
message="Як ми можемо звертатися до вас?">
<input value={this.state.login}
onChange={this.handleChange} />
<button onClick={this.handleSignUp}>
Sign Me Up!
Зареєструйте мене!
</button>
</Dialog>
);
Expand All @@ -156,17 +156,17 @@ class SignUpDialog extends React.Component {
}

handleSignUp() {
alert(`Welcome aboard, ${this.state.login}!`);
alert(`Ласкаво просимо на борт, ${this.state.login}!`);
}
}
```

[**Try it on CodePen**](https://codepen.io/gaearon/pen/gwZbYa?editors=0010)
[**Спробувати на CodePen**](https://codepen.io/gaearon/pen/gwZbYa?editors=0010)

## So What About Inheritance? {#so-what-about-inheritance}
## То що з приводу наслідування? {#so-what-about-inheritance}

At Facebook, we use React in thousands of components, and we haven't found any use cases where we would recommend creating component inheritance hierarchies.
У Facebook ми використовуємо React у тисячах компонентів і ми не знайшли жодного випадку використання, в якому б ми могли порадити створення ієрархій наслідування компонентів.

Props and composition give you all the flexibility you need to customize a component's look and behavior in an explicit and safe way. Remember that components may accept arbitrary props, including primitive values, React elements, or functions.
Пропси і композиція дають вам всю необхідну гнучкість, щоб налаштувати вигляд і поведінку компонента в явний і безпечний спосіб. Пам'ятайте, що компоненти можуть приймати довільні пропси, включно з примітивами, React-елементами чи функціями.

If you want to reuse non-UI functionality between components, we suggest extracting it into a separate JavaScript module. The components may import it and use that function, object, or a class, without extending it.
Якщо ви хочете повторно використати функціональність, котра не відноситься до інтерфейсу користувача, ми рекомендуємо витягнути її в окремий JavaScript модуль. Компоненти можуть імпортувати його і використувати функцію, об'єкт чи клас без наслідування.