← Назад к вопросам

В чем разница между Redux и ReduxToolKit?

1.8 Middle🔥 241 комментариев
#State Management

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Redux vs Redux Toolkit: полное сравнение

Redux Toolkit (RTK) — это официально рекомендованный способ написания Redux логики. Он включает в себя инструменты для упрощения типичных Redux сценариев, снижения количества кода и предотвращения распространенных ошибок. Redux Toolkit на 100% совместим с обычным Redux, но значительно упрощает разработку.

История

Redux был создан Дэн Абрамовым в 2015 году и стал стандартом управления состоянием в React приложениях.

Redux Toolkit был создан командой Redux в 2019 году как официальное решение для упрощения Redux разработки.

Основные различия

1. Объем кода

Redux (traditional):

// action types
const INCREMENT = "INCREMENT";
const DECREMENT = "DECREMENT";

// action creators
const increment = () => ({ type: INCREMENT });
const decrement = () => ({ type: DECREMENT });

// reducer
const counterReducer = (state = 0, action) => {
  switch (action.type) {
    case INCREMENT:
      return state + 1;
    case DECREMENT:
      return state - 1;
    default:
      return state;
  }
};

// store
import { createStore } from "redux";
const store = createStore(counterReducer);

Redux Toolkit:

import { createSlice } from "@reduxjs/toolkit";

const counterSlice = createSlice({
  name: "counter",
  initialState: 0,
  reducers: {
    increment: (state) => state + 1,
    decrement: (state) => state - 1,
  },
});

export const { increment, decrement } = counterSlice.actions;
export default counterSlice.reducer;

Redux Toolkit требует в 2-3 раза меньше кода.

2. Неизменяемость (Immutability)

Redux требует ручной заботы об неизменяемости:

// Нужно осторожно обновлять объекты
const todoReducer = (state = [], action) => {
  switch (action.type) {
    case ADD_TODO:
      // Неправильно: мутирует состояние
      // state.push(action.payload);
      // return state;
      
      // Правильно: создает новый массив
      return [...state, action.payload];
    
    case UPDATE_TODO:
      // Неправильно: мутирует объект
      // state[0].title = "new title";
      
      // Правильно: создает новые объекты
      return state.map(todo =>
        todo.id === action.payload.id
          ? { ...todo, ...action.payload }
          : todo
      );
    
    default:
      return state;
  }
};

Redux Toolkit использует Immer.js для безопасной работы с состоянием:

const todoSlice = createSlice({
  name: "todos",
  initialState: [],
  reducers: {
    addTodo: (state, action) => {
      // Можно писать как мутирующий код, Immer позаботится
      state.push(action.payload);
    },
    updateTodo: (state, action) => {
      const todo = state.find(t => t.id === action.payload.id);
      if (todo) {
        // Выглядит как мутация, но на самом деле безопасно
        todo.title = action.payload.title;
      }
    },
  },
});

3. DevTools интеграция

Redux:

import { createStore, applyMiddleware, compose } from "redux";

const composeEnhancers =
  typeof window === "object" && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
    ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({})
    : compose;

const store = createStore(
  rootReducer,
  composeEnhancers(applyMiddleware(...middleware))
);

Redux Toolkit:

import { configureStore } from "@reduxjs/toolkit";

const store = configureStore({
  reducer: {
    counter: counterReducer,
    todos: todosReducer,
  },
});
// Redux DevTools уже интегрированы!

4. Обработка асинхронных операций

Redux:

import { createStore, applyMiddleware } from "redux";
import thunk from "redux-thunk";

// Action creator
const fetchUsers = () => {
  return (dispatch) => {
    dispatch({ type: "FETCH_START" });
    fetch("/api/users")
      .then(res => res.json())
      .then(data => {
        dispatch({ type: "FETCH_SUCCESS", payload: data });
      })
      .catch(error => {
        dispatch({ type: "FETCH_ERROR", payload: error });
      });
  };
};

const store = createStore(rootReducer, applyMiddleware(thunk));

Redux Toolkit:

import { createAsyncThunk, createSlice, configureStore } from "@reduxjs/toolkit";

// Асинхронный thunk
const fetchUsers = createAsyncThunk(
  "users/fetchUsers",
  async (_, { rejectWithValue }) => {
    try {
      const response = await fetch("/api/users");
      if (!response.ok) throw new Error("Failed to fetch");
      return await response.json();
    } catch (error) {
      return rejectWithValue(error.message);
    }
  }
);

const usersSlice = createSlice({
  name: "users",
  initialState: { data: [], loading: false, error: null },
  extraReducers: (builder) => {
    builder
      .addCase(fetchUsers.pending, (state) => {
        state.loading = true;
      })
      .addCase(fetchUsers.fulfilled, (state, action) => {
        state.loading = false;
        state.data = action.payload;
      })
      .addCase(fetchUsers.rejected, (state, action) => {
        state.loading = false;
        state.error = action.payload;
      });
  },
});

const store = configureStore({
  reducer: usersSlice.reducer,
});

5. Middleware

Redux:

// Кастомный middleware
const logger = store => next => action => {
  console.log("Action:", action);
  const result = next(action);
  console.log("New state:", store.getState());
  return result;
};

const store = createStore(
  rootReducer,
  applyMiddleware(logger, thunk)
);

Redux Toolkit:

import { configureStore } from "@reduxjs/toolkit";

const store = configureStore({
  reducer: rootReducer,
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware().concat(logger),
});
// Включены: thunk, logger в разработке по умолчанию

6. Query (RTK Query)

Redux Toolkit Query — это встроенная библиотека для управления кэшем данных от сервера:

import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";

const api = createApi({
  reducerPath: "api",
  baseQuery: fetchBaseQuery({ baseUrl: "https://api.example.com" }),
  endpoints: (builder) => ({
    getUsers: builder.query({
      query: () => "/users",
    }),
    updateUser: builder.mutation({
      query: (id, data) => ({
        url: `/users/${id}`,
        method: "PUT",
        body: data,
      }),
    }),
  }),
});

export const { useGetUsersQuery, useUpdateUserMutation } = api;

Таблица сравнения

ПараметрReduxRedux Toolkit
Объем кодаБольшойМинимальный
Кривая обученияКрутаяПологая
DevToolsРучная настройкаПо умолчанию
Immer интеграцияНетДа
Async обработкаredux-thunkcreateAsyncThunk
API запросыВручнуюRTK Query
ПроизводительностьХорошоОтлично
TypeScript поддержкаХорошоОтлично
МидлварыНужно устанавливатьВключены по умолчанию
РекомендацияНе рекомендуется для новых проектовОфициально рекомендуется

Миграция с Redux на Redux Toolkit

// До: Redux
const INCREMENT = "INCREMENT";
const increment = () => ({ type: INCREMENT });
const reducer = (state = 0, action) => {
  switch (action.type) {
    case INCREMENT:
      return state + 1;
    default:
      return state;
  }
};

// После: Redux Toolkit
const slice = createSlice({
  name: "counter",
  initialState: 0,
  reducers: {
    increment: (state) => state + 1,
  },
});

export const { increment } = slice.actions;
export default slice.reducer;

Вывод

Выбирайте Redux Toolkit, если:

  • Начинаете новый проект
  • Хотите писать меньше boilerplate кода
  • Нужна встроенная поддержка DevTools
  • Нужна работа с асинхронностью
  • Нужен RTK Query для API запросов

Redux может быть полезен только, если:

  • Работаете с очень старым codebases
  • Нужна минимальная зависимость от библиотек

Официально Redux рекомендует использовать Redux Toolkit для всех новых разработок.