Redux — это библиотека для управления состоянием (state management) JavaScript-приложений, чаще всего используемая с React. Это предсказуемый контейнер состояния, работающий по принципу единого источника истины (single source of truth).
import { createStore } from 'redux';
const store = createStore(rootReducer);
Все состояние приложения хранится в одном объекте-хранилище (store).
Состояние в Redux нельзя изменять напрямую — только через редьюсеры (reducers).
Единственный источник истины
Состояние всего приложения хранится в одном дереве объектов (store).
Состояние только для чтения
Изменять состояние можно только через экшены (actions).
Изменения через чистые функции
Редьюсеры (reducers) описывают как состояние трансформируется в ответ на экшены.
Объекты, которые описывают что произошло:
const addTodo = (text) => ({
type: 'ADD_TODO',
payload: { text, id: Date.now() }
});
Чистые функции, которые принимают предыдущее состояние и экшен, возвращают новое состояние:
const todosReducer = (state = [], action) => {
switch(action.type) {
case 'ADD_TODO':
return [...state, action.payload];
default:
return state;
}
};
Создается комбинацией редьюсеров:
import { combineReducers, createStore } from 'redux';
const rootReducer = combineReducers({
todos: todosReducer,
user: userReducer
});
const store = createStore(rootReducer);
Для side-эффектов (например, асинхронных операций):
import { applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
const store = createStore(rootReducer, applyMiddleware(thunk));
Глобальное состояние приложения
Когда разные компоненты на разных уровнях вложенности нуждаются в одних данных.
Сложные state-логики
Когда логика обновления состояния становится слишком сложной для useState/useReducer.
Отслеживание изменений состояния
Redux DevTools позволяют детально анализировать каждое изменение.
Серверный рендеринг (SSR)
Удобно передавать состояние с сервера клиенту.
Упрощенный API для работы с Redux:
import { createSlice, configureStore } from '@reduxjs/toolkit';
const todosSlice = createSlice({
name: 'todos',
initialState: [],
reducers: {
addTodo: (state, action) => {
state.push(action.payload); // Можно "мутировать" благодаря Immer
}
}
});
const store = configureStore({
reducer: {
todos: todosSlice.reducer
}
});
Пример подключения к React:
import { Provider } from 'react-redux';
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);