Если вы устали от шаблонного boilerplate-кода, сложной настройки store и ручного написания редьюсеров в Redux, то Redux Toolkit — это именно то, что прописал доктор. Этот официальный, рекомендованный подход кардинально упрощает работу с глобальным состоянием в React-приложениях, позволяя сосредоточиться на логике, а не на конфигурации. Давайте разберемся, как быстро и эффективно начать им пользоваться.
Что такое Redux Toolkit и зачем он нужен?
Redux Toolkit (часто сокращают до RTK) — это официальный пакет инструментов, созданный командой Redux для решения ключевых проблем «ванильного» Redux. Его главная цель — устранить избыточность кода, предоставить умные настройки по умолчанию и встроить лучшие практики прямо в API. Вместо того чтобы вручную прописывать action types, action creators и сложные редьюсеры со switch/case, вы получаете лаконичные и мощные инструменты вроде createSlice и configureStore.
Важно: Redux Toolkit не является новой библиотекой. Это стандартный способ написания логики Redux. Все новые проекты на Redux должны использовать именно его.
Быстрая установка и настройка
Начать невероятно просто. В вашем существующем React-проекте выполните команду установки:
npm install @reduxjs/toolkit react-redux
Или, если вы создаете проект с нуля, используйте официальный шаблон:
npx create-react-app my-app --template redux
Создаем store за минуту
Раньше создание store было ритуалом с подключением middleware (например, Redux Thunk) и devTools. Теперь всё в одной функции:
import { configureStore } from '@reduxjs/toolkit';
import counterReducer from '../features/counter/counterSlice';
export const store = configureStore({
reducer: {
counter: counterReducer,
},
});
Функция configureStore по умолчанию включает Redux DevTools Extension и добавляет промежуточное ПО (middleware) для обработки асинхронной логики (thunk). Это готовая к работе конфигурация!
Сердце RTK: createSlice
Это самый революционный API в наборе. createSlice автоматически генерирует action creators и action types на основе редьюсеров, которые вы описываете. Вы определяете начальное состояние (initialState), набор «редьюсеров» (функций для изменения состояния) и получаете «слайс» (slice), содержащий всё необходимое.
import { createSlice } from '@reduxjs/toolkit';
const counterSlice = createSlice({
name: 'counter', // Префикс для action types
initialState: { value: 0 },
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;
// Экспортируем редьюсер для store
export default counterSlice.reducer;
Внутри редьюсеров в createSlice вы можете писать мутирующую логику (как в примере выше). Это возможно благодаря библиотеке Immer, которая включена в RTK «из коробки». Под капотом она создает корректное неизменяемое обновление состояния.
Асинхронная логика с createAsyncThunk
Для работы с API и асинхронными операциями RTK предоставляет createAsyncThunk. Он генерирует три экшена: pending, fulfilled и rejected, которые вы можете обработать в своем слайсе.
import { createAsyncThunk, createSlice } from '@reduxjs/toolkit';
import { fetchUserData } from './api';
export const fetchUserById = createAsyncThunk(
'users/fetchByIdStatus',
async (userId, thunkAPI) => {
const response = await fetchUserData(userId);
return response.data;
}
);
const usersSlice = createSlice({
name: 'users',
initialState: { entities: [], loading: 'idle' },
extraReducers: (builder) => {
builder
.addCase(fetchUserById.pending, (state) => { state.loading = 'loading'; })
.addCase(fetchUserById.fulfilled, (state, action) => {
state.loading = 'idle';
state.entities.push(action.payload);
});
},
});
Подключение к React-компоненту
Используйте стандартные хуки react-redux, но теперь с чистой и простой логикой:
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { increment, decrement } from './counterSlice';
function Counter() {
const count = useSelector((state) => state.counter.value);
const dispatch = useDispatch();
return (
{count}
);
}
FAQ: Часто задаваемые вопросы
Redux Toolkit обязателен для использования Redux?
Строго говоря, нет. Но это официально рекомендованный подход. Он включает лучшие практики, уменьшает объем шаблонного кода и предотвращает распространенные ошибки. Для новых проектов — это единственный разумный выбор.
Можно ли использовать RTK с TypeScript?
Да, Redux Toolkit изначально написан на TypeScript и предлагает превосходную типизацию из коробки. createSlice и createAsyncThunk автоматически выводят типы для ваших экшенов и состояния.
Что такое RTK Query и как она связана с Toolkit?
RTK Query — это мощное дополнение, встроенное в Redux Toolkit (начиная с версии 1.6). Она предназначена для полного управления fetching, кэшированием и синхронизацией данных с сервера. Если ваше приложение активно работает с API, обязательно изучите и ее.
Стоит ли мигрировать старый проект на Redux Toolkit?
Однозначно стоит рассмотреть. Миграция может быть постепенной: вы можете начать использовать RTK для новых фич, оставляя старый код. Это улучшит поддерживаемость и сократит объем кода в долгосрочной перспективе.