React: Redux Toolkit
Теория: Подробнее о слайсах
Начнем погружаться в Toolkit с главного — со слайсов. Что бы мы ни делали внутри слайсов, в конце концов они генерируют обычные редьюсеры и действия, которые затем передаются в Redux. Другими словами, слайсы не добавляют новых возможностей в сам Redux. Они автоматизируют рутину, сокращают количество кода и делают удобнее управление действиями и состоянием.
Чтобы создать слайс, нам нужно минимум три компонента — имя, начальное состояние и набор редьюсеров. Рассмотрим подробнее:
Имя (name) используется как префикс в названии действия. Оно помогает в отладке — мы видим, откуда взялось действие:
Начальное состояние (initialState) — это базовая структура данных и какие-то изначальные данные, если они есть (например, значение 0 для счетчика). Данные, которые нужно выкачать по API, к начальным не относятся. Они заполняются уже потом через действия.
Редьюсеры (reducers) в Toolkit очень похожи на редьюсеры в самом Redux, но здесь есть несколько важных отличий. Каждый редьюсер соответствует конкретному действию, поэтому внутри нет конструкции switch. Сами редьюсеры при этом очень маленькие. Внутри редьюсеров происходит прямое изменение состояния. Как такое возможно?
Когда состояние становится глубоко вложенным, работать с Redux становится неудобно. Запрет на прямое изменение порождает сложные конструкции, которые приходится писать при обновлении глубоко спрятанных данных:
Раньше для решения этой проблемы использовалось множество разных библиотек. Все библиотеки вносили еще один уровень абстракции и делали работу сложнее.
Так продолжалось до тех пор, пока не появилась библиотека Immer. Она позволяет отследить прямые изменения внутри объекта так, чтобы обновлять оригинал без мутаций — то есть создавать копию в стиле Redux:
В отличие от прямого изменения baseState, Immer работает как редьюсеры в Redux, то есть в неизменяемом стиле. Еще один пример:
[Каждый редьюсер в Toolkit работает как колбек из Immer, в который передается draft. Теперь мы можем мутировать состояние, но внутри все работает так, как будто мы этого не делаем.
Благодаря такому подходу сохраняются все возможности, которые предоставляет Redux, включая его DevTool — утилиту для анализа происходящего в браузере. Мы получили плюсы от обоих миров, сохранив всю экосистему Redux.
Наконец, перейдем к экспортам. Функция createSlice() генерирует редьюсер и действия к нему. Все это официальная документация рекомендует экспортировать так:
- Редьюсер — по умолчанию
- Действия — по именам
Посмотрим на таком примере:
Каждый новый редьюсер нужно не забывать добавлять в хранилище:
Передаваемый в редьюсер объект формирует глобальное состояние Redux. В примере выше состояние будет выглядеть так:




