Комбінування Reducers (Root Reducer)
Комбінування 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).
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 робить наступне:
- Він викликає
todosReducer(state.todos, action). - Він викликає
userReducer(state.user, action). - Він викликає
uiReducer(state.interface, action). - Він збирає результати від кожного з них і повертає новий великий об'єкт стану.
default: state).Практичний приклад
Давайте створимо повноцінну структуру для store.
Тепер store.getState() поверне:
{
todos: [],
visibilityFilter: 'SHOW_ALL'
}
Цей патерн є стандартом для всіх Redux додатків. Навіть в Redux Toolkit, який ми будемо вчити пізніше, під капотом використовується той самий принцип.
Тепер, коли у нас є робочий Store, настав час підключити його до React.
Логіка Reducers
Ми вже знаємо, що редюсер — це чиста функція (state, action) => newState. Але як писати складні редюсери, коли стан — це не просто одне число, а складний об'єкт?
Підключення до React (React-Redux)
Сам по собі Redux нічого не знає про React. Щоб "пожружити" їх, нам потрібна офіційна бібліотека-прошарок: React Redux.