> 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/combinereducers.md).

# Комбинирование редьюсеров

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

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

## Комбинирование редьюсеров

Зачем? Когда наше приложение разрастается, хочется еще больше модульности, чтобы каждый кусочек кода отвечал за конкретную часть. Так же и с редьюсерами, мы можем разбить наш главный редьюсер на несколько более мелких, и с помощью `combineReducers` из пакета `redux` собрать их воедино. Причем, абсолютно никакой магии, *combineReducers* просто возвращает "составной" редьюсер.

Для нашего приложения, можно выделить следующие reducer'ы (согласно [схеме](https://maxfarseer.gitbooks.io/redux-course-ru/content/sample_app_reducer.jpg)):

* user
* page

Создадим их:

*src/reducers/user.js*

```javascript
const initialState = {
  name: 'Аноним'
}

export default function user(state = initialState) {
  return state
}
```

*src/reducers/page.js*

```javascript
const initialState = {
  year: 2016,
  photos: []
}

export default function page(state = initialState) {
  return state
}
```

Обновим точку входа для редьюсеров:

*src/reducers/index.js*

```javascript
import { combineReducers } from 'redux'
import page from './page'
import user from './user'

export default combineReducers({
  page,
  user
})
```

Обратите внимание, что структура объекта, которым можно описать все состояние нашего приложения - не изменилась. Все осталось также.

```javascript
{
    user: {             
        name: 'Аноним'  
    }                   
    page: {             
        year: 2016,     
        photos: []      
    }                   
}
```

Тем не менее, в браузере у нас нерабочее приложение. В чем же проблема?

Ответ кроется в работе функции *connect* и в функции *mapStateToProps* из нашего файла *App.js*. Сейчас у нас там написано следующее:

```javascript
function mapStateToProps (state) {
  return {
    user: state
  }
}
```

Что можно перевести так: возьми полностью "стейт" приложения и присоедини его в переменную user, дабы она была доступна из компонета *App.js* как `this.props.user`

И действительно, если взглянуть в dev tools, все так и есть: ![App с неправильными свойствами](https://721505618-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LvLmy8wH1HhL0UsjoVp%2F-LvLmyaitqCV1tR5_kQb%2F-LvLnS9fazjxpJpRn-x-%2Fapp_with_wrong_props.jpg?generation=1575561845580649\&alt=media)

Здесь, я предложу простую задачку на понимание происходящего. Измените компонент *App.js* и функцию *mapStateToProps* так, чтобы получить следующую картину:

![App с новыми свойствами](https://721505618-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LvLmy8wH1HhL0UsjoVp%2F-LvLmyaitqCV1tR5_kQb%2F-LvLnS9h-p6UWEd3HSlD%2Fapp_with_props.jpg?generation=1575561845583739\&alt=media)

Ответ:

*src/containers/App.js*

```javascript
import React, { Component } from 'react'
import { connect } from 'react-redux'

class App extends Component {
  render() {
    const { name } = this.props.user // (1)
    const { year, photos } = this.props.page // (2)
    return <div>
      <p>Привет, {name}!</p>
      <p>У тебя {photos.length} фото за {year} год</p>
    </div>
  }
}

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

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

*Сносками (1) и (2) я пометил связь.*

Супер, сейчас у нас в *user* - попадет все из нашего приложения, что будет связано с пользователем , а в *page* - попадет все что связано с отображением соответствующего блока (год и массив фото).

Второй раз за главу, возникает вопрос - зачем? Ответ прежний: модульность, меньший объем кода в каждом файле и лучшая читаемость. А **главное**, мы так добьемся меньшего количества ненужных обновлений, представьте: пользователь кликнул на кнопку "2015", и обновился блок *page*, при этом блок *user* остался **бы** не тронутым вообще, если **бы** он являлся отдельным компонентом.

Нам ничего не мешает исправить это. Продолжим в следующей главе.

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

Полезные ссылки:

* [combineReducers](https://github.com/rackt/redux/blob/master/docs/api/combineReducers.md) (офф.документация)
