Если вы устали от шаблонного кода, сложной настройки и бесконечных папок с редьюсерами в Redux, то Redux Toolkit — это ваш спасательный круг. Этот официальный пакет кардинально упрощает работу с глобальным состоянием в React-приложениях, превращая многословную рутину в элегантный и эффективный процесс. Давайте разберемся, как начать использовать его уже сегодня.
Что такое Redux Toolkit и зачем он нужен?
Redux Toolkit (часто сокращают до RTK) — это официальный, рекомендуемый подход к написанию логики Redux. Создатели Redux поняли, что классическая настройка требует слишком много шаблонного кода (boilerplate). RTK инкапсулирует лучшие практики и предоставляет набор инструментов, которые автоматизируют рутинные задачи.
Ключевая философия: Redux Toolkit не заменяет Redux, а является его стандартной «оберткой». Он включает в себя утилиты для настройки хранилища (store), создания редьюсеров и действий, выполнения асинхронной логики и многого другого.
Быстрая установка и настройка
Начать можно в два счета. Если у вас есть готовый React-проект (созданный, например, через Create React App или Vite), просто выполните команду установки:
npm install @reduxjs/toolkit react-redux
Или, если вы используете Yarn:
yarn add @reduxjs/toolkit react-redux
Создаем первое хранилище (Store)
В классическом Redux создание store — это многострочная история с `createStore`, комбинированием редьюсеров и подключением middleware. В RTK это одна функция:
// app/store.js
import { configureStore } from '@reduxjs/toolkit';
import counterReducer from '../features/counter/counterSlice';
export const store = configureStore({
reducer: {
counter: counterReducer,
// Сюда добавляем другие редьюсеры
},
});
Функция `configureStore` по умолчанию уже включает самые полезные middleware (например, для обработки асинхронных действий и проверки на мутацию состояния).
Сердце RTK: создание «слайса» (slice)
Концепция «слайса» (slice) — это главное нововведение. Слайс автоматически генерирует действия (actions) и редьюсер для определенной части состояния.
// features/counter/counterSlice.js
import { createSlice } from '@reduxjs/toolkit';
const initialState = {
value: 0,
};
export const counterSlice = createSlice({
name: 'counter', // Уникальное имя слайса
initialState,
reducers: {
// Здесь описываем функции-редьюсеры и автоматически генерируемые действия
increment: (state) => {
state.value += 1; // Можно «мутировать» состояние! Благодаря Immer.
},
decrement: (state) => {
state.value -= 1;
},
incrementByAmount: (state, action) => {
state.value += action.payload;
},
},
});
// Экспортируем сгенерированные действия (action creators)
export const { increment, decrement, incrementByAmount } = counterSlice.actions;
// Экспортируем редьюсер
export default counterSlice.reducer;
Волшебство Immer: Обратите внимание, что в редьюсерах мы как будто напрямую изменяем состояние (`state.value += 1`). На самом деле, RTK использует библиотеку Immer, которая создает «черновик» состояния и применяет изменения иммутабельно. Это делает код невероятно чистым и читаемым.
Подключаем React-компонент
Подключение компонента к хранилищу происходит через хуки `useSelector` и `useDispatch` из `react-redux`.
// features/counter/Counter.js
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { increment, decrement, incrementByAmount } from './counterSlice';
export function Counter() {
const count = useSelector((state) => state.counter.value);
const dispatch = useDispatch();
return (
{count}
);
}
Асинхронные операции с createAsyncThunk
Для работы с API и асинхронной логикой RTK предлагает `createAsyncThunk`. Он автоматически генерирует действия для состояний запроса: pending (в процессе), fulfilled (успешно), rejected (с ошибкой).
// features/posts/postsSlice.js
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
import { fetchPostsApi } from './api';
export const fetchPosts = createAsyncThunk('posts/fetchPosts', async () => {
const response = await fetchPostsApi();
return response.data;
});
const postsSlice = createSlice({
name: 'posts',
initialState: { items: [], status: 'idle', error: null },
extraReducers: (builder) => {
builder
.addCase(fetchPosts.pending, (state) => {
state.status = 'loading';
})
.addCase(fetchPosts.fulfilled, (state, action) => {
state.status = 'succeeded';
state.items = action.payload;
})
.addCase(fetchPosts.rejected, (state, action) => {
state.status = 'failed';
state.error = action.error.message;
});
},
});
Почему стоит перейти на Redux Toolkit?
- Меньше шаблонного кода: Слайсы генерируют действия автоматически.
- Лучшая производительность: Встроенная оптимизация и DevTools.
- Стандартизация: Официальный, рекомендуемый подход от создателей Redux.
- Immer под капотом: Пишите простой мутирующий код, получайте иммутабельные обновления.
- RTK Query: Мощный инструмент для работы с API, идущий в комплекте (но это уже тема для отдельной статьи).
FAQ: Часто задаваемые вопросы
Redux Toolkit — это новый Redux?
Нет, это официальный набор инструментов и лучших практик для работы с Redux. Сам Redux остается ядром.
Обязательно ли использовать createSlice?
Нет, но крайне рекомендуется. Это основной и самый эффективный способ организации кода в RTK.
Можно ли мигрировать старый проект на Redux Toolkit постепенно?
Да, абсолютно. `configureStore` может работать с классическими редьюсерами, а новые части состояния можно внедрять через слайсы.
Что такое RTK Query и нужно ли его использовать?
RTK Query — это мощное решение для кэширования, синхронизации и управления серверным состоянием, встроенное в RTK. Для проектов с активной работой с API он может кардинально сократить объем кода.
Подходит ли Redux Toolkit для больших проектов?
Да, более чем. Его архитектура со слайсами идеально масштабируется и помогает поддерживать порядок в кодовой базе.