Зарегистрируйтесь для доступа к 15+ бесплатным курсам по программированию с тренажером

Мидлвары JS: Redux (React)

Мидлвары (middlewares) — это функции, которые последовательно вызываются в процессе обновления данных в хранилище. Они относятся к продвинутым техникам использования Redux.

В этом уроке мы посмотрим на них не с точки зрения написания, а исключительно с точки зрения использования. Они помогут нам подключать различные библиотеки, причем с самого начала использования их в React.

Как работают мидлвары

Общий принцип такой:

  • Сначала мидлвары встраиваются в хранилище при его создании
  • Затем во время диспатчинга (отправки действий) данные проходят через мидлвары и только затем попадают в редьюсер

Схематично этот принцип можно показать так:

Работа мидлваров в Redux

Такая организация позволяет программистам расширять библиотеки новой функциональностью, не переписывая исходный код Redux под конкретную задачу.

Мидлвары используются в таких задачах, как:

  • Логирование
  • Оповещение об ошибках
  • Работа с асинхронным API
  • Маршрутизация

Как устроены мидлвары

Рассмотрим типичную структуру мидлвары, которая отвечает, например, за логирование. Любая мидлвара в Redux — это композиция из трех вложенных функций:

// Мидлвара со вложенными стрелочными функциями
const logger = (store) => (next) => (action) => {
  console.group(action.type);
  console.info('dispatching', action);
  const result = next(action);
  console.log('next state', store.getState());
  console.groupEnd();
  return result;
};

У всех мидлвар одинаковая структура из трех компонентов. Рассмотрим ее на примере выше:

  1. Внешняя функция

    Именно она является мидлварой и передается в метод applyMiddleware(). Функция получает на вход объект store, который содержит методы dispatch() и getState() для работы с флоу Redux.

  2. Первая вложенная функция

    Её аргументом будет особая функция next(). Вызов этой функции в теле мидлвары с действием в качестве аргумента может прокидывать действие дальше по цепочке мидлвар.

    Но если next() вызван в последней мидлваре в цепочке (цепочка может состоять и из одной мидлвары), она диспатчит действие, отправляя его в редьюсер и вызывая обновление стейта.

  3. Вторая вложенная функция

    Это функция, замыкающая в себе действие action при его диспатчинге. Всякое действие в приложении, отправляемое в редьюсер, будет перехватываться мидлварой.

В силу особенности функции next(), наш логгер содержит асинхронную логику. Мы не дожидаемся окончания работы логгера, а передаем действие дальше по цепочке мидлвар вплоть до редьюсера, вызывая обновление стейта строчкой const result = next(action);.

Только потом, уже после цепочки мидлвар и обновления стейта, мы логируем новое состояние стора. Таким образом, все инструкции в логгере после вызова next() выполняются как бы в будущем, в котором последующие мидлвары и редьюсер уже закончили работу.

Как использовать мидлвары

Теперь посмотрим, как подключить мидлвары:

import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';

const store = createStore(
  reducer,
  /* preloadedState, */
  applyMiddleware(thunk)
)

Выше вы видите мидлвару thunk. Перед тем, как передать его в функцию createStore, нужно применить к нему функцию applyMiddleware.

Обратите внимание, что мидлвару мы передаем вторым параметром, хотя в предыдущем уроке вторым параметром шел initState. Так происходит потому, что функция createStore проверяет тип второго параметра и в зависимости от этого понимает, что перед ней.

В общем случае она принимает три параметра:

  • Редьюсер
  • Начальное состояние
  • Мидлвары

Если мидлвар несколько, придется воспользоваться еще одной функцией:

import { createStore, applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk';
import logger from 'redux-logger';

const store = createStore(
  reducer,
  /* preloadedState, */
  compose(
    applyMiddleware(thunk),
    applyMiddleware(logger)
  ),
)

В этом случае в хранилище передается результат функции compose(), при этом функция compose() принимает на вход мидлвары.

Теперь мы подобрались к главному. Для Redux написано специальное браузерное расширение Redux DevTools. Установите его в свой браузер.

Расширение для Redux

Ниже код подключения этого расширения к хранилищу:

const reduxDevtools = window.__REDUX_DEVTOOLS_EXTENSION__;
const store = createStore(
   reducer,
   /* preloadedState, */
    reduxDevtools && reduxDevtools(),
 );

Обратите внимание, что при работе с расширением функции applyMiddleware не требуется.

В будущих уроках вам не придется подключать расширение руками. Мы уже сделали это за вас. Все, что нужно — установить его и не забывать им пользоваться. Это ваш главный помощник в отладке на протяжении всего курса.


Дополнительные материалы

  1. Официальная документация ReduxDevTools

Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты.

Для полного доступа к курсу нужен базовый план

Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
1000
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно.

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов
Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и соглашаетесь с «Условиями использования»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff
Рекомендуемые программы

С нуля до разработчика. Возвращаем деньги, если не удалось найти работу.

Иконка программы Фронтенд-разработчик
Профессия
Разработка фронтенд-компонентов для веб-приложений
6 октября 10 месяцев
Иконка программы Fullstack-разработчик
Профессия
Разработка фронтенд- и бэкенд-компонентов для веб-приложений
6 октября 16 месяцев

Используйте Хекслет по-максимуму!

  • Задавайте вопросы по уроку
  • Проверяйте знания в квизах
  • Проходите практику прямо в браузере
  • Отслеживайте свой прогресс

Зарегистрируйтесь или войдите в свой аккаунт

Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и соглашаетесь с «Условиями использования»