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

Как изменить состояние в Redux?

2.2 Middle🔥 181 комментариев
#State Management

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

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

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

Как изменить состояние в Redux

В Redux есть строгая архитектура для изменения состояния. Это не похоже на обычный setState в React - здесь всё происходит через Actions и Reducers.

Основной паттерн Redux

Изменение состояния - это трёх-этапный процесс:

// 1. Action (описание что произошло)
const INCREMENT = 'INCREMENT';
const action = { type: INCREMENT, payload: 5 };

// 2. Dispatch (отправить действие)
store.dispatch(action);

// 3. Reducer (обновить состояние)
function counterReducer(state = 0, action) {
  switch(action.type) {
    case INCREMENT:
      return state + action.payload;
    default:
      return state;
  }
}

Современный подход: Redux Toolkit

Redux Toolkit упростил синтаксис благодаря createSlice:

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

const counterSlice = createSlice({
  name: 'counter',
  initialState: { value: 0 },
  reducers: {
    increment: (state, action) => {
      // Immer.js позволяет мутировать state
      state.value += action.payload;
    },
    decrement: (state) => {
      state.value -= 1;
    }
  }
});

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

Использование в компоненте

import { useDispatch, useSelector } from 'react-redux';
import { increment } from './counterSlice';

function Counter() {
  const dispatch = useDispatch();
  const count = useSelector(state => state.counter.value);

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => dispatch(increment(5))}>
        +5
      </button>
    </div>
  );
}

Асинхронные операции: Thunks

Для API запросов используем createAsyncThunk:

import { createAsyncThunk } from '@reduxjs/toolkit';

const fetchUser = createAsyncThunk(
  'user/fetchUser',
  async (userId, { rejectWithValue }) => {
    try {
      const response = await fetch(`/api/users/${userId}`);
      return await response.json();
    } catch (error) {
      return rejectWithValue(error.message);
    }
  }
);

const userSlice = createSlice({
  name: 'user',
  initialState: { data: null, loading: false, error: null },
  extraReducers: (builder) => {
    builder
      .addCase(fetchUser.pending, (state) => {
        state.loading = true;
      })
      .addCase(fetchUser.fulfilled, (state, action) => {
        state.loading = false;
        state.data = action.payload;
      })
      .addCase(fetchUser.rejected, (state, action) => {
        state.loading = false;
        state.error = action.payload;
      });
  }
});

Ключевые правила

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

// Плохо - мутируем прямо
state.count = 5;

// Хорошо - создаём новый объект
return { ...state, count: 5 };

// С Redux Toolkit - Immer сделает это сам
state.count = 5; // работает, как если бы создавали новый объект

Reducers должны быть pure functions:

  • Без побочных эффектов
  • Без API запросов
  • Без изменения входящих параметров

Альтернативы Redux

Для современных проектов рассмотри:

  • Zustand - проще, меньше boilerplate
  • Jotai/Recoil - атомарное состояние
  • TanStack Query (React Query) - для асинхронного состояния
  • Context API + useReducer - встроенное в React

Вывод

Жизненный цикл изменения состояния: Action -> Dispatch -> Reducer -> новое состояние -> компонент перерендер. Redux Toolkit сделал это значительно проще, убрав много boilerplate кода.

Как изменить состояние в Redux? | PrepBro