> For the complete documentation index, see [llms.txt](https://max-frontend.gitbook.io/redux-course-ru/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://max-frontend.gitbook.io/redux-course-ru/struktura_prilozheniya/konteineri_i_komponenti.md).

# Контейнеры и компоненты

*ОБНОВЛЕНИЕ 2018: Вышло* [*второе издание*](https://maxfarseer.gitbooks.io/redux-course-ru-v2/content/) *(современный код и версии пакетов, данное издание УСТАРЕЛО)*

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

## Контейнеры и компоненты

Прежде чем мы разобьем App.js на компоненты User.js и Page.js хотелось бы отметить про разделение на "компоненты" и "контейнеры", иначе называемые: "глупые" и "умные" компоненты, "Presentational" и "Container" и быть может как-то еще.

Позволю себе в очередной раз прибегнуть к [офф.документации](http://redux.js.org/docs/basics/UsageWithReact.html) и перевести таблицу различий, которая отлично и кратко отражает суть.

|                       | Компонент (глупый)                 | Контейнер (умный)                                         |
| --------------------- | ---------------------------------- | --------------------------------------------------------- |
| Цель                  | Как это выглядит (разметка, стили) | Как это работает (получение данных, обновление состояния) |
| Осведомлен о Redux    | Нет                                | Да                                                        |
| Для считывания данных | Читает данные из props             | Подписан на Redux state (состояние)                       |
| Для изменения данных  | Вызывает callback из props         | Отправляет (dispatch) Redux действие (actions)            |
| Пишутся               | Вручную                            | Обычно, генерируются Redux                                |

Магия таблиц обычно проявляется не сразу. Если переписать наше приложение, а потом взглянуть сюда еще раз - многое станет гораздо яснее. Предлагаю так и поступить. Поехали!

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

*src/components/User.js*

```javascript
import React, { PropTypes, Component } from 'react'

export default class User extends Component {
  render() {
    const { name } = this.props
    return <div>
      <p>Привет, {name}!</p>
    </div>
  }
}

User.propTypes = {
  name: PropTypes.string.isRequired
}
```

*src/components/Page.js*

```javascript
import React, { PropTypes, Component } from 'react'

export default class Page extends Component {
  render() {
    const { year, photos } = this.props
    return <div>
      <p>У тебя {photos.length} фото за {year} год</p>
    </div>
  }
}

Page.propTypes = {
  year: PropTypes.number.isRequired,
  photos: PropTypes.array.isRequired
}
```

Наш файл App.js уже практически и есть container, он даже лежит в соответствующей папке. Изменим-с...

*src/containers/App.js*

```javascript
import React, { Component } from 'react'
import { connect } from 'react-redux'
import User from '../components/User'
import Page from '../components/Page'

class App extends Component {
  render() {
    const { user, page } = this.props
    return <div>
      <User name={user.name} />
      <Page photos={page.photos} year={page.year} />
    </div>
  }
}

function mapStateToProps (state) {
  return {
    user: state.user,
    page: state.page
  }
}

export default connect(mapStateToProps)(App)
```

Теперь можно обновлять компоненты *Page* и *User* независимо друг от друга. Чем мы и займемся в следующей главе, изучая *actions*.
