Проверяет понимание различий между useReducer, useState и Redux, а также умение выбирать подходящий инструмент для управления состоянием.
useReducer — это хук React, который управляет сложным состоянием через редюсер (функцию, обрабатывающую действия). Его стоит использовать:
Когда состояние сложное (много связанных значений, например, форма с валидацией).
Когда логика обновления нетривиальна (много условий, побочных эффектов).
Для оптимизации производительности (редюсеры помогают избежать лишних ререндеров).
Как упрощенная альтернатива Redux (если не нужен глобальный стейт).
useReducer?useReducer принимает три аргумента:
Редюсер — функцию вида (state, action) => newState, которая определяет, как состояние должно измениться в ответ на действие.
Начальное состояние.
(Опционально) Функцию для ленивой инициализации состояния.
Возвращает массив из двух элементов:
Текущее состояние.
Функцию dispatch, которая отправляет действия в редюсер.
Простой пример счетчика:
import { useReducer } from 'react';
function counterReducer(state, action) {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
case 'decrement':
return { count: state.count - 1 };
default:
return state;
}
}
function Counter() {
const [state, dispatch] = useReducer(counterReducer, { count: 0 });
return (
<div>
<p>Count: {state.count}</p>
<button onClick={() => dispatch({ type: 'increment' })}>+</button>
<button onClick={() => dispatch({ type: 'decrement' })}>-</button>
</div>
);
}useReducer вместо useState?useState отлично подходит для простого состояния, например, для хранения одного значения или примитивной структуры данных. Однако useReducer становится предпочтительным выбором в следующих случаях:
Состояние имеет сложную структуру. Например, если вам нужно управлять формой с множеством полей, валидацией и зависимыми значениями.
Логика обновления состояния сложная. Если изменения состояния зависят от предыдущего состояния или требуют обработки множества условий, редюсер помогает организовать код лучше.
Нужно минимизировать ререндеры. useReducer позволяет группировать несколько изменений состояния в одно обновление, что может улучшить производительность.
Пример сложной формы с useReducer:
function formReducer(state, action) {
switch (action.type) {
case 'setUsername':
return { ...state, username: action.payload };
case 'setPassword':
return { ...state, password: action.payload };
case 'validate':
return { ...state, errors: validateForm(state) };
case 'submit':
return { ...state, isSubmitting: true };
default:
return state;
}
}
function Form() {
const [state, dispatch] = useReducer(formReducer, {
username: '',
password: '',
errors: {},
isSubmitting: false,
});
const handleSubmit = (e) => {
e.preventDefault();
dispatch({ type: 'validate' });
if (Object.keys(state.errors).length === 0) {
dispatch({ type: 'submit' });
}
};
return (
<form onSubmit={handleSubmit}>
<input
value={state.username}
onChange={(e) => dispatch({ type: 'setUsername', payload: e.target.value })}
/>
{state.errors.username && <p>{state.errors.username}</p>}
<button disabled={state.isSubmitting}>Отправить</button>
</form>
);
}useReducer вместо Redux?Redux — инструмент для управления глобальным состоянием приложения, но он не всегда нужен. useReducer может быть отличной альтернативой в следующих случаях:
Состояние локальное. Если состояние нужно только внутри одного компонента или небольшой группы компонентов, useReducer будет проще и удобнее.
Не нужны дополнительные возможности Redux. Например, если вам не требуются middleware (как Redux Thunk или Saga), DevTools или time-travel debugging.
Хочется избежать лишней сложности. Redux требует настройки хранилища (store), действий (actions) и редюсеров, что может быть избыточно для небольших проектов.
Когда выбрать Redux:
Глобальное состояние. Если состояние должно быть доступно во многих частях приложения.
Сложные сайд-эффекты. Например, асинхронные запросы, которые обрабатываются через middleware.
Инструменты разработчика. Redux DevTools предоставляют мощные возможности для отладки.
useState — для простого состояния (например, флаги, счетчики).
useReducer — для сложного состояния (формы, многошаговые процессы).
Redux — для глобального состояния и продвинутых сценариев.