Fundamentals

Чисті функції та Іммутабельність

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

Чисті функції та Іммутабельність

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

Чисті Функції (Pure Functions)

Концепція прийшла з функціонального програмування. Функція вважається "чистою", якщо вона відповідає двом критеріям:

  1. Детермінованість: Для одних і тих самих вхідних аргументів вона завжди повертає однаковий результат.
  2. Відсутність побічних ефектів (No Side Effects): Вона не змінює нічого за своїми межами (глобальні змінні, стан DOM, мережеві запити тощо) і не змінює свої аргументи.

Приклади

// Чиста функція
// Завжди повертає a + b.
// Не змінює нічого зовні.
function add(a, b) {
  return a + b;
}
Золоте правило Redux: Редюсери (Reducers) МУСЯТЬ бути чистими функціями.

Це означає, що в редюсері ЗАБОРОНЕНО:

  • Робити Math.random(), Date.now().
  • Робити API запити (fetch, axios).
  • Змінювати змінні за межами редюсера.
  • Мутувати (змінювати) аргументи state або action.

Іммутабельність (Immutability)

Іммутабельність означає, що дані не можна змінювати після створення. Якщо ви хочете змінити дані, ви повинні створити копію з новими значеннями.

У JavaScript об'єкти та масиви є мутабельними (змінними) за посиланням. Це корінь зла в Redux, якщо не бути обережним.

Мутація vs Іммутабельність

const user = { name: 'Ivan', age: 25 };

// ❌ МУТАЦІЯ
// Ми змінили існуючий об'єкт.
// Посилання на об'єкт залишилося тим самим!
user.age = 26; 

// ✅ ІММУТАБЕЛЬНЕ ОНОВЛЕННЯ
// Ми створили НОВИЙ об'єкт.
// Посилання змінилося!
const updatedUser = { ...user, age: 26 };

Чому Redux вимагає іммутабельності?

  1. Продуктивність (Reference Equality Check): Redux перевіряє, чи змінився стан, порівнюючи посилання (prevProps === nextProps).
    • Якщо ми зробимо мутацію (obj.prop = 1), посилання на obj не зміниться. React/Redux подумає, що нічого не змінилося, і не оновить компонент.
    • Якщо ми створимо новий об'єкт, посилання буде новим, і Redux зрозуміє: "Ага, дані змінилися, треба перемалювати UI".
  2. Передбачуваність та Time Travel: Щоб "відмотати час назад", Redux DevTools зберігає копії попередніх станів. Якщо ви мутуєте стан, ви перезаписуєте історію. Повернутися назад стає неможливо.

Патерни Іммутабельного Оновлення

Вам доведеться часто писати такий код у класичному Redux (або використовувати Redux Toolkit, який робить це за вас).

1. Оновлення об'єкта

Використовуйте Spread Operator (...).

const state = {
  loading: false,
  data: { id: 1, text: 'Hello' }
};

// ❌ Погано
state.loading = true;

// ✅ Добре
return {
  ...state,        // Копіюємо всі поля (data)
  loading: true    // Перезаписуємо loading
};

2. Оновлення вкладеного об'єкта

Це найскладніше. Потрібно копіювати кожен рівень вкладеності (Shallow Copy).

// Хочемо змінити state.data.text
return {
  ...state,
  data: {
    ...state.data, // Копіюємо поля всередині data
    text: 'Bye'    // Оновлюємо text
  }
};

3. Додавання в масив

const todos = [1, 2, 3];

// ❌ Погано (push мутує масив)
todos.push(4);

// ✅ Добре
const newTodos = [...todos, 4];

4. Видалення з масиву

Використовуйте filter, бо він повертає новий масив.

// Видалити todo з id=2
const newTodos = state.todos.filter(todo => todo.id !== 2);

5. Оновлення елемента в масиві

Використовуйте map.

// Перемкнути статус todo з id=2
const newTodos = state.todos.map(todo => {
  if (todo.id === 2) {
    // Знайшли потрібний? Повертаємо копію зі змінами
    return { ...todo, completed: !todo.completed };
  }
  // Не той? Повертаємо без змін
  return todo;
});
Цей код виглядає громіздким, чи не так? Саме тому в сучасному Redux (Toolkit) використовується бібліотека Immer, яка дозволяє писати мутабельний код, а під капотом перетворює його на іммутабельний. Але про це пізніше. Спочатку навчимося "ходити пішки".

Тепер, коли ми озброєні теорією, давайте напишемо наш перший реальний Redux код.

👉 Далі: Створення Store та Перший Reducer

Copyright © 2026