React: Redux Toolkit
Теория: Редьюсеры
Мы называем состоянием все, что находится в хранилище. При этом не все состояния одинаково полезны. Документация Redux предлагает такую классификацию:
- Domain data — это данные, которые нужно отображать, использовать и модифицировать (например, загруженный с сервера список пользователей)
- App state — данные, которые определяют поведение приложения (например, открытый URL)
- UI state — данные, которые определяют внешний вид (например, вывод списка в виде плиток)
Хранилище — это ядро приложения, поэтому данные внутри него должны описываться в терминах domainData и appState, а не как дерево компонентов UI.
Например, способ формирования состояния state.leftPane.todoList.todos — плохая идея. Очень редко дерево компонентов отражается напрямую на структуру состояния, и это нормально. Представление зависит от данных, а не данные от представления.
Типичная структура состояния выглядит так:
Как уже говорилось в курсе JS: React, структура состояния должна напоминать базу данных. Все максимально плоско и нормализованно:
С такой структурой намного проще писать реакции на действия, добавлять новые данные и удалять старые. Вложенность небольшая, поэтому все просто. Но появляется другая проблема — чем больше сущностей, тем тяжелее становится редьюсер. Постепенно он превращается в огромный кусок кода, который делает все.
Чтобы решить эту проблему, можно использовать механизм, встроенный в Redux. Он позволяет создавать множественные редьюсеры и комбинировать их друг с другом. Работает это так:
- Для каждого свойства верхнего уровня пишется свой редьюсер
- С помощью функции
combineReducers()все редьюсеры объединяются в корневой редьюсер (root) - Корневой редьюсер используется для создания хранилища
В итоге действия попадают во все редьюсеры, собранные внутри combineReducers():
В каждый редьюсер приходит state, но это не все состояние хранилища, а только та часть, которая лежит в соответствующем свойстве. В примере выше в редьюсер todosReducer будет передаваться состояние из свойства todos, а в commentsReducer из comments. Эта привязка происходит через объект, который передается в combineReducers():
Схематично комбинацию редьюсеров можно обозначить так:

А еще редьюсеры могут быть даже вложенными. Для этого не нужны никакие специальные средства — это обычные функции, принимающие одни данные и возвращающие другие данные.
С таким подходом появляется одна особенность, которая вначале может испугать. Каждый редьюсер имеет доступ только к своей части состояния, поэтому действия, порождающие изменения сразу в нескольких местах, будут повторяться в разных редьюсерах:
Правильный подход в этом случае — повторять часть case в нужных редьюсерах.
Рекомендуемые программы
Завершено
0 / 11




