Classic Redux

Підключення до React (React-Redux)

Сам по собі Redux нічого не знає про React. Щоб "пожружити" їх, нам потрібна офіційна бібліотека-прошарок: React Redux.

Підключення до React (React-Redux)

Сам по собі Redux нічого не знає про React. Щоб "пожружити" їх, нам потрібна офіційна бібліотека-прошарок: React Redux.

npm install react-redux

Вона надає нам два ключові інструменти:

  1. <Provider> — компонент, який робить стор доступним для всього додатку.
  2. Hooks (useSelector, useDispatch) — для взаємодії компонентів зі стором.

Крок 1: Provider

Ми маємо обгорнути наш кореневий компонент (зазвичай <App>) у <Provider> і передати йому наш створений store.

index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import store from './store'; // Наш store з попередніх уроків
import App from './App';

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
);

Під капотом Provider використовує React Context, тому нам не потрібно передавати пропси вручну через всі компоненти.

Крок 2: Читання даних (useSelector)

Щоб отримати дані зі стору в компоненті, використовуємо хук useSelector.

import { useSelector } from 'react-redux';

const CounterDisplay = () => {
  // Функція-селектор приймає весь state і повертає потрібну частину
  const count = useSelector(state => state.value);

  return <h1>Поточний рахунок: {count}</h1>;
};

Особливості useSelector:

  1. Автоматична підписка: Компонент автоматично підписується на зміни стору.
  2. Розумний ре-рендер: Якщо state.value змінилося, компонент перемалюється. Якщо змінилося щось інше (наприклад, state.user), компонент не буде перемальовуватися (за умови, що селектор повертає те саме значення).
  3. Порівняння посилань: useSelector використовує суворе порівняння (===).

Обережно з об'єктами! Якщо ваш селектор повертає новий об'єкт кожного разу, компонент буде ре-рендеритися постійно, навіть якщо дані не змінилися.

// ❌ Погано: створює новий об'єкт { a, b } при кожному виклику
const { a, b } = useSelector(state => ({ a: state.a, b: state.b }));

// ✅ Добре: викликати useSelector кілька разів
const a = useSelector(state => state.a);
const b = useSelector(state => state.b);

Крок 3: Зміна даних (useDispatch)

Щоб відправити action, використовуємо хук useDispatch.

import { useDispatch } from 'react-redux';

const CounterControls = () => {
  const dispatch = useDispatch();

  return (
    <div>
      <button onClick={() => dispatch({ type: 'INCREMENT' })}>+</button>
      <button onClick={() => dispatch({ type: 'DECREMENT' })}>-</button>
    </div>
  );
};

Історична довідка: connect()

У старих туторіалах (до 2019 року) ви можете побачити функцію connect та mapStateToProps. Це старий спосіб (Higher-Order Component), який використовувався в класових компонентах.

// Legacy Style 👴
class Counter extends React.Component { ... }

const mapStateToProps = state => ({ count: state.value });
const mapDispatchToProps = { increment };

export default connect(mapStateToProps, mapDispatchToProps)(Counter);

Сьогодні використання Hooks є стандартом. connect все ще працює, але використовувати його в новому коді не рекомендується.


Ми навчилися працювати з синхронними даними. Але що робити, коли нам потрібно завантажити дані з сервера? Redux "з коробки" не вміє працювати з асинхронністю. Нам потрібен Middleware.

👉 Далі: Асинхронність та Redux Thunk

Copyright © 2026