Что такое Reducer в Redux?

«Что такое Reducer в Redux?» — вопрос из категории Other, который задают на 33% собеседований Data Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Reducer (редюсер) в Redux — это чистая функция, которая определяет, как состояние (state) приложения изменяется в ответ на отправленное действие (action). Это единственное место, где логика обновления состояния должна быть описана.

Сигнатура функции:

function reducer(previousState, action) {
  // Вычисляем и возвращаем следующее состояние
  return nextState;
}

Три фундаментальных принципа Reducer:

  1. Чистота: Не производит сайд-эффектов (вызовов API, мутаций).
  2. Иммутабельность: Не изменяет переданный previousState. Вместо этого создаёт и возвращает новый объект состояния.
  3. Детерминированность: Для одних и тех же входных state и action всегда возвращает одинаковый nextState.

Практический пример из моего опыта: Допустим, у нас есть состояние для управления списком задач (todo list).

// Начальное состояние
const initialState = {
  todos: [],
  filter: 'SHOW_ALL'
};

// Reducer
function todoApp(state = initialState, action) {
  switch (action.type) {
    case 'ADD_TODO':
      // ВАЖНО: Не мутируем старый массив, создаём новый
      return {
        ...state, // Копируем все поля предыдущего состояния
        todos: [
          ...state.todos, // Копируем старый массив todos
          { // Добавляем новый элемент
            id: action.payload.id,
            text: action.payload.text,
            completed: false
          }
        ]
      };

    case 'TOGGLE_TODO':
      return {
        ...state,
        todos: state.todos.map(todo =>
          // Если это не тот todo, возвращаем как есть
          todo.id !== action.payload.id ? todo :
          // Иначе создаём новый объект todo с изменённым полем
          { ...todo, completed: !todo.completed }
        )
      };

    case 'SET_FILTER':
      return {
        ...state,
        filter: action.payload.filter
      };

    // На действие по умолчанию возвращаем неизменённое состояние
    default:
      return state;
  }
}

Почему это важно: Такая архитектура делает изменения состояния предсказуемыми и легко тестируемыми. Вы можете логировать каждое действие и состояние «до/после», что неоценимо при отладке сложного взаимодействия в приложении.