> Можно ли делать асинхронные запросы внутри редюсера Redux и почему (JavaScript)

Уровень: senior · Роль: frontend · Категория: Технические вопросы

Компании: Домклик

Стек: JavaScript

> Пример ответа

Нет, делать асинхронные запросы напрямую внутри редюсера Redux нельзя и не следует. Редюсеры в Redux должны быть чистыми функциями - они принимают предыдущее состояние и экшен, и синхронно возвращают новое состояние без побочных эффектов.

Причины:

  1. Нарушение предсказуемости. Асинхронные операции (например, fetch или setTimeout) вносят недетерминизм: результат запроса может зависеть от сети, времени или других внешних факторов. Редюсер теряет свойство детерминированности, что усложняет отладку и тестирование.
  2. Нарушение принципа чистоты. Редюсер не должен изменять ничего за пределами своей области (например, вызывать API или изменять глобальные переменные). Асинхронные запросы - это побочный эффект.
  3. Проблемы с временем выполнения. Редюсеры выполняются синхронно и не могут "ждать" ответа от сервера. Попытка сделать асинхронный вызов внутри редюсера приведёт к тому, что экшен завершится до получения данных, и состояние обновится некорректно.

Правильный подход: использовать middleware (например, redux-thunk, redux-saga или redux-observable). Они позволяют обрабатывать асинхронные действия до того, как экшен попадёт в редюсер. Например, с redux-thunk вы можете диспатчить функцию, которая выполняет запрос, а затем диспатчит обычный синхронный экшен с полученными данными в редюсер.

Пример с redux-thunk:

JAVASCRIPT
// action creator
const fetchUser = (id) => async (dispatch) => {
dispatch({ type: 'FETCH_USER_REQUEST' });
try {
const response = await fetch(`/api/users/${id}`);
const data = await response.json();
dispatch({ type: 'FETCH_USER_SUCCESS', payload: data });
} catch (error) {
dispatch({ type: 'FETCH_USER_FAILURE', error });
}
};
// редюсер остаётся чистым
const userReducer = (state = initialState, action) => {
switch (action.type) {
case 'FETCH_USER_SUCCESS':
return { ...state, user: action.payload };
default:
return state;
}
};

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

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью