For the complete documentation index, see llms.txt. This page is also available as Markdown.

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

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

Для нашего приложения, можно выделить следующие reducer'ы (согласно схеме из предыдущих глав):

  • user

  • page

Создадим их:

src/reducers/user.js

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

export function userReducer(state = initialState) {
  return state
}

src/reducers/page.js

const initialState = {
  year: 2018,
  photos: [],
}

export function pageReducer(state = initialState) {
  return state
}

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

src/reducers/index.js

Обновим configureStore:

src/store/configureStore.js

Посмотрим что у нас теперь "консолится" в компоненте <App />, а так же в React dev tools.

broken-app-with-combineReducer

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

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

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

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

hello-anonymous-zero-photos

Ответ:

src/containers/App.js

Работа функции mapStateToProps многих вводит в ступор. В данной функции, мы хотим отрезать от нашего общего пирога (Store) только те кусочки (редьюсеры), которые нам нужны.

Еще можно применить аналогию: мы приклеиваем в props компонента, данные из тех редьюсеров, которые нам требуются.

А если быть более точным, то мы не только получаем в this.props.XXX данные, которым нам нужны, но мы еще и подписываемся на изменение этих данных.

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

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

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

Исходный код на текущий момент.

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

Last updated