Redux — предсказуемый контейнер управления состоянием для JavaScript-приложений, созданный Дэном Абрамовым в 2015 году. Redux реализует однонаправленный поток данных на основе архитектуры Flux: состояние хранится в единственном Store, изменяется только через чистые функции Reducer и инициируется через Action с Dispatch. По данным npm Trends, Redux сохраняет более 7 миллионов еженедельных загрузок, оставаясь стандартом для управления состоянием в React Native и веб-приложениях.
Главное
Redux — архитектурный паттерн и библиотека для управления состоянием, основанный на трёх принципах: единственный источник правды (single source of truth), состояние только для чтения (read-only) и изменения через чистые функции. В отличие от 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 без фреймворков.
Unidirectional data flow — ключевой принцип Redux, при котором данные движутся строго в одном направлении: View → Action → Dispatch → Reducer → Store → View. Никакой компонент не может изменить Store напрямую. View только подписывается на изменения через useSelector или connect и инициирует изменения через dispatch.
Цикл работы Redux: пользователь нажимает кнопку → компонент вызывает dispatch({ type: 'INCREMENT' }) → Store передаёт Action в Root Reducer → Reducer вычисляет новое состояние → Store уведомляет подписчиков → View перерисовывается с новыми данными. Этот цикл гарантирует, что каждый Change имеет явную причину в виде конкретного 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 для нормализации коллекций сущностей. Предоставляет built-in 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 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также