← Назад к вопросам
Как изменить состояние через reducer в Redux?
2.0 Middle🔥 191 комментариев
#State Management
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI3 апр. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Что такое Redux и Reducer
Redux - это предсказуемое хранилище состояния. Reducer - это чистая функция, которая берет текущее состояние и action, и возвращает новое состояние.
Основной цикл Redux
Action -> Dispatch -> Reducer -> New State -> Components Update
Решение 1: Базовый Redux reducer
export const INCREMENT = 'INCREMENT';
export const DECREMENT = 'DECREMENT';
export const SET_NAME = 'SET_NAME';
const initialState = {
count: 0,
name: ''
};
export function counterReducer(state = initialState, action) {
switch(action.type) {
case INCREMENT:
return {
...state,
count: state.count + 1
};
case DECREMENT:
return {
...state,
count: state.count - 1
};
case SET_NAME:
return {
...state,
name: action.payload
};
default:
return state;
}
}
Решение 2: Redux Toolkit (современный подход)
import { createSlice } from '@reduxjs/toolkit';
const initialState = {
count: 0,
name: '',
status: 'idle'
};
const counterSlice = createSlice({
name: 'counter',
initialState,
reducers: {
increment: (state) => {
state.count += 1;
},
decrement: (state) => {
state.count -= 1;
},
setName: (state, action) => {
state.name = action.payload;
},
reset: (state) => {
state.count = 0;
state.name = '';
}
}
});
export const { increment, decrement, setName, reset } = counterSlice.actions;
export default counterSlice.reducer;
Решение 3: Использование dispatch в компонентах
import { useSelector, useDispatch } from 'react-redux';
import { increment, decrement, setName } from './slices/counterSlice';
export function Counter() {
const dispatch = useDispatch();
const count = useSelector(state => state.counter.count);
const name = useSelector(state => state.counter.name);
return (
<div>
<h1>Counter: {count}</h1>
<p>Name: {name}</p>
<button onClick={() => dispatch(increment())}>
Increment
</button>
<button onClick={() => dispatch(decrement())}>
Decrement
</button>
<input
type="text"
value={name}
onChange={(e) => dispatch(setName(e.target.value))}
placeholder="Enter name"
/>
</div>
);
}
Решение 4: Асинхронные действия (Thunks)
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
export const fetchUser = createAsyncThunk(
'user/fetchUser',
async (userId, { rejectWithValue }) => {
try {
const response = await fetch(`/api/users/${userId}`);
if (!response.ok) throw new Error('Failed');
return 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;
state.error = null;
})
.addCase(fetchUser.fulfilled, (state, action) => {
state.loading = false;
state.data = action.payload;
})
.addCase(fetchUser.rejected, (state, action) => {
state.loading = false;
state.error = action.payload;
});
}
});
Ключевые принципы
- Reducers - чистые функции: нет побочных эффектов
- Immutability: не мутируй состояние (Redux Toolkit Immer решает)
- Single source of truth: одно глобальное состояние
- Actions и Action Creators: явные описания изменений
- Dispatch: отправляешь action, redux вызывает reducer