Стоит ли выносить вызов fetch на уровень Redux
Что проверяют
Отличаете ли вы серверный кэш от состояния интерфейса и понимаете ли, где живут побочные эффекты. Ответ уровня «да, всегда выносим в thunk» сегодня звучит устаревшим: ждут рассуждение о том, что за данные и кому они нужны.
Как отвечать
Разделите состояние на два вида. Клиентское: открыт ли модал, выбранный фильтр, черновик формы. Серверный кэш: список, карточка, справочник, которые на самом деле принадлежат бэкенду, а у вас лежит копия с ограниченным сроком годности.
Для второго есть специальные инструменты: RTK Query, если проект уже на Redux Toolkit, либо React Query. Они дают ровно то, ради чего запрос обычно и тащат в хранилище: дедупликацию одинаковых вызовов, кэш по ключу, статусы загрузки и ошибки, инвалидацию, отмену, повторные попытки. Писать это руками на трёх экшенах значит переизобретать кэш.
Когда хранилище оправдано: данные нужны несвязанным веткам дерева, есть оптимистичные обновления, нужен единый перехват ошибок авторизации. Когда не оправдано: данные нужны одному экрану и умирают вместе с ним. И отметьте, что сам запрос в редьюсере невозможен в принципе, редьюсер обязан быть чистым, эффект живёт в middleware или снаружи.
Где спотыкаются
Складывают в хранилище каждый ответ сервера. Появляются ручные флаги загрузки на каждый список, нормализация, которую никто не поддерживает, и устаревшие данные, которые некому инвалидировать.
Считают, что redux-thunk разрешает асинхронность внутри редьюсера. Редьюсер остаётся синхронным и чистым, thunk это промежуточный слой перед ним, и путаница в этом месте слышна интервьюеру сразу.
Забывают про гонки. Два быстрых запроса возвращаются в обратном порядке, и в хранилище оседает устаревший ответ. Нужны AbortController, сверка идентификатора запроса или встроенная в инструмент отмена.