useReducer vs useState
Що робить useReducer
useReducer - це хук React, який дозволяє керувати станом через функцію-редюсер (reducer).
Він схожий на принцип Redux:
стан змінюється не напряму, а через "дію" (action).
Синтаксис
javascript
const [state, dispatch] = useReducer(reducer, initialState);state- поточний станdispatch- функція, яка відправляє "дію"reducer(state, action)- функція, яка отримує поточний стан і "дію", і повертає новий стан
Простий приклад
javascript
function reducer(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(reducer, { count: 0 });
return (
<div>
<p>{state.count}</p>
<button onClick={() => dispatch({ type: "increment" })}>+</button>
<button onClick={() => dispatch({ type: "decrement" })}>-</button>
</div>
);
}Як це працює:
- При кліку React викликає
dispatch({ type: "increment" }). - React викликає
reducer(state, action). - Reducer повертає новий стан -> React перемальовує компонент.
Чим useReducer відрізняється від useState
| Критерій | useState | useReducer |
|---|---|---|
| Тип стану | Простий (одне значення) | Складний (об'єкт, масив, логіка оновлень) |
| Оновлення | setState(newValue) | dispatch({ type, payload }) |
| Логіка оновлення | Прямо в компоненті | Винесена в окрему функцію (reducer) |
| Коли використовувати | Прості кейси (лічильник, форма, перемикач) | Коли стан складний або залежить від різних дій |
| Підходить для | Малих компонентів | Великих / складних станів |
| Схоже на | Вбудована альтернатива Redux | Міні-Redux в одному компоненті |
Приклад порівняння
Варіант з useState
javascript
const [count, setCount] = useState(0);
const increment = () => setCount(count + 1);
const decrement = () => setCount(count - 1);Просто, але погано масштабується, якщо логіка складна.
Варіант з useReducer
javascript
function reducer(state, action) {
switch (action.type) {
case "increment":
return { ...state, count: state.count + 1 };
case "decrement":
return { ...state, count: state.count - 1 };
case "reset":
return { ...state, count: 0 };
default:
return state;
}
}
const [state, dispatch] = useReducer(reducer, { count: 0 });Тепер ти можеш централізовано керувати логікою - зручно, коли багато розгалужень або станів.
Коли краще використовувати useReducer
Використовуй useReducer, коли:
- Стан складний (наприклад, об'єкт з кількома полями).
- Логіка оновлення залежить від різних типів дій.
- Кілька частин коду можуть оновлювати той самий стан.
- Хочеш розділити логіку (reducer) і UI-компонент.
Приклади:
- Форма з валідацією
- Багатоетапний процес (wizard / onboarding)
- Список елементів з фільтрацією, сортуванням, додаванням, видаленням
Приклад "форма" на useReducer
javascript
function formReducer(state, action) {
switch (action.type) {
case "changeField":
return { ...state, [action.field]: action.value };
case "reset":
return { name: "", email: "" };
default:
return state;
}
}
function Form() {
const [form, dispatch] = useReducer(formReducer, { name: "", email: "" });
return (
<form>
<input
value={form.name}
onChange={(e) =>
dispatch({ type: "changeField", field: "name", value: e.target.value })
}
/>
<input
value={form.email}
onChange={(e) =>
dispatch({ type: "changeField", field: "email", value: e.target.value })
}
/>
<button onClick={() => dispatch({ type: "reset" })}>Clear</button>
</form>
);
}Тепер можна легко розширювати форму - просто додаєш новий case.
Підсумок
| Питання | Відповідь |
|---|---|
Що робить useReducer? | Керує станом через функцію-редюсер, реагуючи на "дії" (actions) |
Чим відрізняється від useState? | useState просто зберігає значення, useReducer керує складною логікою |
| Коли використовувати? | При складних або пов'язаних оновленнях |
| Коли не варто? | Для простих чисел, рядків, прапорців - простіше useState |
| Чим схожий на Redux? | Той самий принцип "action -> reducer -> new state", тільки локально |
Коротка відповідь
Для співбесідиPremium
Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.