Redux — передбачуваний контейнер управління станом для JavaScript-додатків, створений Деном Абрамовим у 2015 році. Redux реалізує односпрямований потік даних на основі архітектури Flux: стан зберігається в єдиному Store, змінюється лише через чисті функції Reducer та ініціюється через Action з Dispatch. За даними npm Trends, Redux зберігає понад 7 мільйонів щотижневих завантажень, залишаючись стандартом для управління станом у React Native та веб-додатках.
Головне
Redux — архітектурний патерн та бібліотека для управління станом, заснований на трьох принципах: єдине джерело правди, стан лише для читання та зміни через чисті функції. На відміну від MVC, де модель може змінювати стан непередбачувано, Redux гарантує детермінованість: при однакових вхідних даних результат завжди однаковий.
Redux був натхненний архітектурою Flux від Facebook та мовою Elm. Основна відмінність від Flux — єдиний Store замість кількох. У Redux весь стан додатка — об'єкти, масиви, прапорці завантаження — зберігається в одному дереві. Це спрощує налагодження, тестування та time-travel debugging. Розробник може зберегти весь Store, відтворити послідовність Action і побачити, як змінювався стан на кожному кроці.
За даними опитування State of JS 2025, 68% респондентів, які використовують управління станом, обирають Redux або Redux Toolkit. Інструмент підтримується всіма сучасними фреймворками: React, React Native, Angular, Vue і навіть чистим JavaScript без фреймворків.
Односпрямований потік даних — ключовий принцип Redux, при якому дані рухаються строго в одному напрямку: View → Action → Dispatch → Reducer → Store → View. Жоден компонент не може змінити Store безпосередньо. View лише підписується на зміни через useSelector або connect та ініціює зміни через dispatch.
Цикл роботи Redux: користувач натискає кнопку → компонент викликає dispatch({ type: 'INCREMENT' }) → Store передає Action у Root Reducer → Reducer обчислює новий стан → Store сповіщає підписників → View перемальовується з новими даними. Цей цикл гарантує, що кожна зміна має явну причину у вигляді конкретного Action.
DevTools — вбудований інструмент Redux для моніторингу кожного Action, стану Store та часу виконання. Розробник бачить список усіх відправлених Action, різницю стану (diff) до та після, і може відкотитися до будь-якого попереднього стану. Це робить налагодження складних станів у десятки разів швидшим у порівнянні зі звичайним логуванням.
Store — об'єкт, що містить повне дерево стану додатка. Створюється через configureStore (RTK) або createStore. Store надає три методи: getState() для читання, dispatch(action) для зміни та subscribe(listener) для підписки. У Redux Toolkit Store вже включає middleware, DevTools та підтримку слайсів.
import { configureStore } from '@reduxjs/toolkit'
interface CounterState {
value: number
}
const initialState: CounterState = { value: 0 }
function counterReducer(
state = initialState,
action: { type: string }
): CounterState {
switch (action.type) {
case 'INCREMENT':
return { value: state.value + 1 }
default:
return state
}
}
const store = configureStore({ reducer: counterReducer })
store.dispatch({ type: 'INCREMENT' })
console.log(store.getState()) // { value: 1 }Action та Action Creator — Action це об'єкт з обов'язковим полем type (рядок-константа) та опціональним payload (дані). Action Creator — функція, що повертає Action. У Redux Toolkit використовується createAction для генерації Action з автоматичною типізацією.
Reducer — чиста функція, що отримує поточний стан та Action, повертаючи новий стан. Reducer не повинен: мутувати state (повертається новий об'єкт), викликати API, генерувати випадкові числа або звертатися до Date. Імутабельність забезпечується спред-оператором ... або Immer (вбудований у RTK).
| Компонент | Обов'язок | Обмеження |
|---|---|---|
| Store | Зберігання стану, dispatch, subscribe | Один на додаток |
| Action | Опис наміру змінити стан | Повинен мати type |
| Reducer | Обчислення нового стану | Чиста функція, без побічних ефектів |
| Dispatch | Відправка Action у Reducer | Синхронний за замовчуванням |
| Selector | Видобування даних з Store | Мемоізація через createSelector |
Middleware — ланцюжок функцій, що вбудовується між викликом dispatch та моментом, коли Action досягає Reducer. Кожен middleware отримує Store API та може логувати, модифікувати, затримувати або скасовувати Action. Redux Thunk — стандартний middleware для асинхронних операцій, що дозволяє dispatch-ити функції замість об'єктів.
import { createAsyncThunk } from '@reduxjs/toolkit'
export const fetchUser = createAsyncThunk(
'users/fetchById',
async (userId: number, { rejectWithValue }) => {
const response = await fetch(`/api/users/${userId}`)
if (!response.ok)
return rejectWithValue('Failed to fetch')
return await response.json()
}
)Популярні middleware: Redux Thunk — для простих асинхронних викликів, Redux Saga — для складних сценаріїв з сагами-генераторами (debounce, race, паралельні запити), Redux Observable — на базі RxJS для реактивних потоків. У Redux Toolkit middleware підключається через параметр middleware у configureStore.
За даними опитування State of JS 2025, Thunk використовується в 72% Redux-проектів, Saga — в 18%, Observable — в 5%. Для більшості додатків комбінації Thunk + RTK Query достатньо, щоб покрити 95% сценаріїв асинхронної роботи з даними.
Redux Toolkit (RTK) — офіційний, рекомендований спосіб написання Redux-логіки, випущений у 2019 році. RTK включає configureStore, createSlice, createAsyncThunk та createEntityAdapter, скорочуючи boilerplate Redux на 60-70%. Замість ручного створення Action Creator, Reducer та типів використовується один createSlice.
import { createSlice, PayloadAction } from '@reduxjs/toolkit'
const counterSlice = createSlice({
name: 'counter',
initialState: { value: 0 },
reducers: {
increment(state) { state.value += 1 },
incrementByAmount(state, action: PayloadAction<number>) {
state.value += action.payload
}
}
})
export const { increment, incrementByAmount } = counterSlice.actions
export default counterSlice.reducerRTK Query — вбудоване рішення для роботи з API на основі Redux Toolkit. Дозволяє визначати ендпоїнти декларативно через createApi з автоматичною генерацією хуків, кешуванням, інвалідацією тегів та оптимістичними оновленнями. RTK Query замінює ручне написання Thunk, Reducer та Selector для кожного API-запиту.
Entity Adapter — утиліта createEntityAdapter для нормалізації колекцій сутностей. Надає вбудовані CRUD-ред'юсери, селектори та сортування для масивів об'єктів. Якщо у Store зберігаються списки користувачів, товарів або замовлень — Entity Adapter скорочує код редукування на 80%.
React Native Redux — стандартна зв'язка для мобільних додатків на JavaScript. Redux інтегрується через Provider з react-redux, що обгортає кореневий компонент додатка. Хуки useSelector та useDispatch дають компонентам доступ до стану без props drilling. Persist — redux-persist зберігає Store у AsyncStorage або MMKV, відновлюючи стан після перезапуску додатка.
Middleware для React Native: redux-flipper для дебаггінгу через Flipper, redux-observable для реактивних потоків з нативними драйверами, react-native-mmkv для швидкого персистентного сховища. Навігаційний плагін redux-first-router пов'язує екрани зі Store, дозволяючи відновлювати стан екрана при поверненні.
У React Native Redux використовується разом із network-first стратегією: додаток спочатку намагається завантажити дані з сервера, потім кешує в Store через RTK Query або redux-persist. Офлайн-режим досягається комбінацією Redux + NetInfo + черги Action для повторної відправки при відновленні з'єднання.
Часті запитання
Redux — повноцінне рішення з Store, DevTools, Middleware та незмінним станом. Context API — вбудований механізм React для передачі даних без props drilling. Context підходить для глобальних тем та локалізації, Redux — для складного стану з асинхронними операціями, кешуванням та налагодженням. У великих додатках Context викликає зайві ререндери, Redux з селекторами вирішує цю проблему.
Immer — бібліотека для імутабельної роботи зі станом, вбудована у Redux Toolkit. Immer дозволяє писати ред'юсери так, ніби мутуєш state безпосередньо: state.value += 1. Під капотом Immer створює проксі-об'єкт (draft), відстежує зміни та повертає новий імутабельний об'єкт. Це зменшує обсяг коду ред'юсерів на 50% та усуває випадкові мутації.
Redux-логіка тестується ізольовано: Reducer — чиста функція, достатньо викликати з різними Action та перевірити результат. Action Creator — перевірити повернутий об'єкт. Thunk — замокати API, викликати dispatch та перевірити, які Action були відправлені. Компонент з useSelector — використовувати Provider з тестовим Store у рендерері. Redux DevTools допомагають написати тест, відтворюючи послідовність Action з реальної сесії.
useState достатній для локального стану одного компонента: текст поля, відкрито/закрито модал. Redux потрібен, коли стан розділяється між багатьма екранами, вимагає асинхронної синхронізації (дані з сервера), має зберігатися між перезапусками додатка (persist) або вимагає time-travel налагодження. Для невеликих додатків Redux надлишковий — використовуйте Context + useReducer.
Normalizr — бібліотека для нормалізації вкладених даних у плоску структуру Store. Замість зберігання глибоких об'єктів виду user.posts[0].comments, нормалізація створює словники: entities.users, entities.posts, entities.comments з посиланнями за ID. Це спрощує оновлення однієї сутності у всіх місцях та прискорює селектори. Redux Toolkit рекомендує нормалізовані дані для складних моделей.
Підсумки
Ми розробимо мобільний застосунок під ключ
IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.
Читайте також