Что такое эпики в redux-observable
Что проверяют
Знаете ли вы модель, а не рецепт. redux-observable описывает побочные эффекты как преобразование потока действий, и собеседник смотрит, понимаете ли вы главное: эпик возвращает поток, а отправляет действия в store уже middleware. Попутно проверяется граница между редьюсером и эффектом.
Как отвечать
Эпик это функция, которая принимает поток действий и поток состояния, а возвращает Observable с новыми действиями. В неё приходят действия, уже прошедшие через редьюсеры, поэтому состояние в ней свежее. Всё, что попало в возвращённый поток, middleware отправит в store само, вызывать dispatch внутри не нужно.
const loadUser = (action$, state$) => action$.pipe(
ofType('USER_REQUEST'),
switchMap(({ id }) => ajax.getJSON(`/api/users/${id}`).pipe(
map(user => ({ type: 'USER_SUCCESS', payload: user })),
catchError(err => of({ type: 'USER_FAILURE', payload: err.message })),
)),
);Эпики собираются в корневой через combineEpics, а запускаются вызовом run у middleware уже после создания store. Стоит сказать, ради чего всё это: отмена запроса по действию, задержка ввода, повтор с паузой, очереди и гонки описываются операторами, а не флагами в состоянии.
Где спотыкаются
Ставят обработку ошибки снаружи, на уровне самого потока действий. Первая же неудача завершает поток, эпик умирает навсегда, и фича молча перестаёт работать до перезагрузки страницы. Обработка должна стоять внутри, рядом с запросом.
Берут mergeMap по привычке. Для поиска и подсказок это гонка: ответ на старый ввод приходит последним и затирает актуальный, нужен switchMap. Встречается и обратная ошибка, когда switchMap на сохранении отменяет уже начатую отправку.
Возвращают из эпика действие того же типа, на который он подписан, и получают бесконечный цикл. Рядом соседняя беда: подписываются вручную и возвращают подписку вместо потока, после чего не работает ни отмена, ни отправка действий.