Classic Redux

Комбінування Reducers (Root Reducer)

У реальному додатку ви не будете тримати всю логіку в одному файлі reducer.js. Це зробило б файл безкінечним і нечитабельним.

Комбінування Reducers (Root Reducer)

У реальному додатку ви не будете тримати всю логіку в одному файлі reducer.js. Це зробило б файл безкінечним і нечитабельним.

Redux пропонує елегантне рішення: Reducer Composition (Композиція Редюсерів).

Ідея

Ми розбиваємо наш глобальний стан на "слайси" (скибки/частини). Кожен слайс керується своїм власним маленьким редюсером.

Замість одного гіганта, який знає все про все:

function bigBadReducer(state, action) {
  switch (action.type) {
    case 'ADD_TODO': ...
    case 'SET_USER': ...
    case 'TOGGLE_SIDEBAR': ...
    // 1000 lines later...
  }
}

Ми створюємо спеціалістів:

  • todosReducer: керує масивом завдань.
  • userReducer: керує профілем користувача.
  • uiReducer: керує інтерфейсом.

combineReducers

Redux надає утиліту combineReducers, яка об'єднує ці маленькі функції в одну велику (Root Reducer).

reducers/index.js
import { combineReducers } from 'redux';
import { todosReducer } from './todosReducer';
import { userReducer } from './userReducer';
import { uiReducer } from './uiReducer';

const rootReducer = combineReducers({
  // Ключ тут визначає, як називатиметься поле в стейті!
  todos: todosReducer,
  user: userReducer,
  interface: uiReducer // Можна перейменувати
});

export default rootReducer;

Тепер наш глобальний стан буде виглядати так:

{
  todos: [...],    // Результат роботи todosReducer
  user: { ... },   // Результат роботи userReducer
  interface: { ... } // Результат роботи uiReducer
}

Як це працює під капотом?

Коли ви відправляєте action (store.dispatch(action)), rootReducer робить наступне:

  1. Він викликає todosReducer(state.todos, action).
  2. Він викликає userReducer(state.user, action).
  3. Він викликає uiReducer(state.interface, action).
  4. Він збирає результати від кожного з них і повертає новий великий об'єкт стану.
Важливо розуміти: Кожен action проходить через ВСІ редюсери. Редюсери не "підписуються" на окремі типи екшенів. Вони просто ігнорують ті, які їм не цікаві (повертають default: state).

Практичний приклад

Давайте створимо повноцінну структуру для store.

Тепер store.getState() поверне:

{
  todos: [],
  visibilityFilter: 'SHOW_ALL'
}

Цей патерн є стандартом для всіх Redux додатків. Навіть в Redux Toolkit, який ми будемо вчити пізніше, під капотом використовується той самий принцип.

Тепер, коли у нас є робочий Store, настав час підключити його до React.

👉 Далі: Підключення до React (Provider & Hooks)

Copyright © 2026