# Создание компонента

_ОБНОВЛЕНИЕ 2018: в учебнике хорошая теория, но ему уже два года. Проверяйте версии пакетов. За выходом нового учебника можно следить в_ [_telegram канале_](http://bit.ly/2tS7QUC) _или_ [_twitter_](http://bit.ly/2HADDLE)

_На_ [_канале_](http://bit.ly/2tS7QUC) _так же проводятся бесплатные вебинары, публикуются переводы и авторские материалы,_ [_присоединяйтесь_](http://bit.ly/2tS7QUC)_!_

## Создание компонента

В прошлом разделе, я упомянул, что ReactDOM.render принимает react-компонент (далее буду называть просто "компонент") и DOM-элемент, в который мы хотим "примонтировать" наше приложение.

`<h1>Hello, world!</h1>` - как ни странно, это примитивный компонент.

Пока ничего интересного, но давайте представим такой псевдо-код:

```javascript
var photos = ['images/cat.jpg','images/dog.jpg','images/owl.jpg']

ReactDOM.render(
  <App>
    <Photos photos=photos />
    <LastNews />
    <Comments />
  </App>,
  document.getElementById('root')
);
```

Что примечательного в псевдо-коде? Он очень хорошо читается, ведь очевидно, что наше приложение (App) отображает: фото (кошка, собака, сова), новости (какие-нибудь) и комментарии (тоже какие-нибудь).

Хочу вас обрадовать. React.js код выглядит практически так же. Он отлично читается, так как деление на компоненты позволяет отлично структурировать код.

Давайте создадим примитивный компонент.

_js/App.js_

```javascript
var App = React.createClass({
  render: function() {
    return (
      <div className="app">
        Всем привет, я компонент App!
      </div>
    );
  }
});

ReactDOM.render(
  <App />,
  document.getElementById('root')
);
```

Посмотрите в браузер, вы увидите разметку, которую мы указали в методе Render, нашего компонента App.

![Первый компонент - App](https://2032922960-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LvLmy8nmqH3uUpCfPAD%2F-LvLmydxF5hwFbPJLrLG%2F-LvLn69g4OxHAR_aJAcU%2Ffirst_component.jpg?generation=1575561849705736\&alt=media)

Конечно, кое-что добавил уже сам реакт, например `data-reactid=".0"`, это нормально.

Слово _class_ в javascript является зарезервированным, поэтому внутри JSX синтаксиса необходимо писать _**className**_.

В ReactDOM.render мы передали целиком наш компонент, без свойств.

Запись `<App />` эквивалентна `<App></App>`.

**Итого**: у нас есть компонент `<App />`

Давайте разовьем идею, и добавим что-нибудь внутрь App, и отобразим это как ни в чем не бывало.

_js/App.js_

```javascript
var News = React.createClass({
  render: function() {
    return (
      <div className="news">
        К сожалению, новостей нет.
      </div>
    );
  }
});

var App = React.createClass({
  render: function() {
    return (
      <div className="app">
        Всем привет, я компонент App! Я умею отображать новости.
        <News />
      </div>
    );
  }
});

ReactDOM.render(
  <App />,
  document.getElementById('root')
);
```

Давайте, вновь взглянем на код и поищем примечательные места.

**Во-первых** - мы никак не изменили код внутри ReactDOM.render. Компонент `<App />`, содержит сейчас в себе другой компонент. Но при этом, это никак не влияет на "рендер" всего нашего приложения.

**Во-вторых**, как уже было сказано - компонент `<App />` содержит в себе компонент `<News />`. Да-да! Так же, как если бы это был просто дочерний `<div></div>` элемент.

**В-третьих**, наш компонент `<News />` такой же примитивный, как и App, и содержит всего один (обязательный!) метод _render_.

Задачка на понимание происходящего: создайте компонент `<Comments />` и сделайте, чтобы он отображался после новостей. Текст компонента: "Нет новостей - комментировать нечего."

_Решение для задачи всегда публикуется ниже по тексту, и обычно содержит сначала подсказки, а потом код всего решения._

**Решение**:

_js/App.js_

```javascript
var News = React.createClass({
  render: function() {
    return (
      <div className="news">
        К сожалению, новостей нет.
      </div>
    );
  }
});

var Comments = React.createClass({
  render: function() {
    return (
      <div className="comments">
        Нет новостей - комментировать нечего
      </div>
    );
  }
});

var App = React.createClass({
  render: function() {
    return (
      <div className="app">
        Всем привет, я компонент App! Я умею отображать новости.
        <News />
        <Comments />
      </div>
    );
  }
});

ReactDOM.render(
  <App />,
  document.getElementById('root')
);
```

Откройте браузер, посмотрите разметку страницы. Все как мы написали + data-react атрибуты.

Ощущается некоторое неудобство, при использовании стандартного способа просмотра в консоли. Предлагаю вам установить react devtools (плагин для [хрома](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi), плагин для [мозилы](https://addons.mozilla.org/en-us/firefox/addon/react-devtools/)).

После установки, откройте вкладку React в консоли разработчика. ![react developer tools looks](https://2032922960-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LvLmy8nmqH3uUpCfPAD%2F-LvLmydxF5hwFbPJLrLG%2F-LvLn69oRWbsT2OQkXz7%2Freact-dev-tools.jpg?generation=1575561820417778\&alt=media)

Пытливый читатель уже заметил окошечко "Props". Ок, об этом и поговорим в следующей главе.

[Исходный код](https://github.com/maxfarseer/react-ru-tutorial/tree/create_components) на данный момент.
