# Порефакторим...

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

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

## Порефакторим...

Для начала, удалите вовсе компонент `<Comments />` (и `var Comments =...` соответственно).

Далее, давайте представим: у наших новостей появляются какие-то дополнительные поля, пользователь начинает взаимодействовать с ними, например "пометить как прочитанное" и так далее. Нам было бы удобно, чтобы каждая новость была представлена компонентом.

**Задача**: `<News />` должен рендерить список компонентов `<Article />`. Каждый компонент `<Article />` должен получать соответствующие данные, например: первый экземпляр получит первый элемент массива, второй - второй и так далее.

То есть, раньше в map мы возвращали JSX-разметку. Но мы так же можем возвращать и компонент.

Попробуйте сами, а потом смотрите решение ниже.

Подсказка **#1**: if-else нашего компонента `<News />`

```javascript
if (data.length > 0) {
  newsTemplate = data.map(function(item, index) {
    return (
      <div key={index}>
        <Article data={item} />
      </div>
    )
  })
} else {
  newsTemplate = <p>К сожалению новостей нет</p>
}
```

Подсказка **#2** (по сути решение задачи): компонент `<Article />`

```javascript
var Article = React.createClass({
  render: function() {
    var author = this.props.data.author,
        text = this.props.data.text;

    return (
      <div className="article">
        <p className="news__author">{author}:</p>
        <p className="news__text">{text}</p>
      </div>
    )
  }
});
```

Что любопытно, больше не изменилось ни-че-го.

Замените фразу "всем привет, я компонент App..." на обычный `<h3>` заголовок - "Новости".

```javascript
var App = React.createClass({
  render: function() {
    return (
      <div className="app">
        <h3>Новости</h3>
        <News data={my_news} />
      </div>
    );
  }
});
```

Добавьте красоты (CSS) по вкусу, либо возьмите мой вариант:

*css/app.css*

```css
.none {
  display: none !important;
}

body {
  background: rgba(0, 102, 255, 0.38);
  font-family: sans-serif;
}

p {
  margin: 0 0 5px;
}

.article {
  background: #FFF;
  border: 1px solid rgba(0, 89, 181, 0.82);
  width: 600px;
  margin: 0 0 5px;
  box-shadow: 2px 2px 5px -1px rgb(0, 81, 202);
  padding: 3px 5px;
}

.news__author {
  text-decoration: underline;
  color: #007DDC;
}
.news__count {
  margin: 10px 0 0 0;
  display: block;
}
```

С новыми стилями, код сценария выглядит так:

*js/app.js*

```javascript
var my_news = [
  {
    author: 'Саша Печкин',
    text: 'В четчерг, четвертого числа...'
  },
  {
    author: 'Просто Вася',
    text: 'Считаю, что $ должен стоить 35 рублей!'
  },
  {
    author: 'Гость',
    text: 'Бесплатно. Скачать. Лучший сайт - http://localhost:3000'
  }
];

var Article = React.createClass({
  render: function() {
    var author = this.props.data.author,
        text = this.props.data.text;

    return (
      <div className='article'>
        <p className='news__author'>{author}:</p>
        <p className='news__text'>{text}</p>
      </div>
    )
  }
});

var News = React.createClass({
  render: function() {
    var data = this.props.data;
    var newsTemplate;

    if (data.length > 0) {
      newsTemplate = data.map(function(item, index) {
        return (
          <div key={index}>
            <Article data={item} />
          </div>
        )
      })
    } else {
      newsTemplate = <p>К сожалению новостей нет</p>
    }

    return (
      <div className='news'>
        {newsTemplate}
        <strong className={'news__count ' + (data.length > 0 ? '':'none') }>Всего новостей: {data.length}</strong>
      </div>
    );
  }
});

var App = React.createClass({
  render: function() {
    return (
      <div className='app'>
        <h3>Новости</h3>
        <News data={my_news} />
      </div>
    );
  }
});

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

Обратите внимание, я добавил несколько классов, один из них я добавил к тэгу **strong**. Как вы помните, у нас там было условие:

```javascript
<strong className={data.length > 0 ? '':'none'}>Всего новостей: {data.length}</strong>
```

Так как атрибут *class* (либо в JSX - *classname*) у элемента принимает строку, то можно представить элемент с несколькими классами:

```javascript
<div className={ 'class1' + 'class2' + 'class3' }>text</div>
```

В таком случае к нашему элементу применится ... класс **"class1class2class3"**, что естественно, так как мы забыли пробелы. Наверное, мы хотели сделать так:

```javascript
<div className={ 'class1 ' + 'class2 ' + 'class3' }>text</div>
```

Теперь у нас будет элемент с классами: class1, class2, class3

Именно поэтому, мы и получили следующее выражение:

```javascript
<strong className={'news__count ' + (data.length > 0 ? '':'none') }>Всего новостей: {data.length}</strong>
```

Посмотрим, что вышло в итоге:

![порефакторим screenshot](/files/-LvLn8pE-a2EDerQnoUX) Либо:

![no news рефакторим](/files/-LvLn8pG1Wfuwz5DiUxQ)

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


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://max-frontend.gitbook.io/react-course-ru/porefaktorim.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
