Skip to main content

useReducer() проти useState()

Основна відмінність

ХукДля чого
useStateПростий, незалежний стан (одне значення, коротка логіка)
useReducerСкладна логіка оновлень, багато взаємопов'язаних даних, зрозуміла структура «дій» (actions)

Коли варто використовувати useReducer()

1. Коли логіка оновлення складна або багатоступенева

Якщо в тебе кілька типів змін, що залежать від різних умов -
замість безлічі setState і if, логічніше мати один централізований reducer.

Приклад:

javascript
const [state, dispatch] = useReducer(reducer, { count: 0, step: 1 }); function reducer(state, action) { switch (action.type) { case "increment": return { ...state, count: state.count + state.step }; case "decrement": return { ...state, count: state.count - state.step }; case "setStep": return { ...state, step: action.payload }; default: return state; } }

Тут useReducer зручніший, ніж три окремих useState.

2. Коли стани взаємопов'язані між собою

Якщо зміна одного поля впливає на інші - useReducer дозволяє
керувати ними в одному місці, а не в десятках setState.

Приклад:

javascript
function formReducer(state, action) { switch (action.type) { case "CHANGE_FIELD": return { ...state, [action.field]: action.value }; case "RESET": return initialForm; default: return state; } }

Керування формою в одному редьюсері - простіше і надійніше, ніж 5 окремих useState.

3. Коли потрібна передбачувана поведінка і «Redux-підхід»

Якщо ти хочеш, щоб оновлення були прозорими, тестованими і централізованими
(наприклад, як у Redux) - useReducer робить це вбудованими засобами React.

«Редьюсер робить стан детермінованим:
та сама дія → завжди той самий новий стан».

4. Коли оновлення залежать від попереднього стану

Замість написання купи setState(prev => ...),
редьюсер вирішує це за тебе - вся логіка вже всередині reducer().

5. Коли ти хочеш використовувати контекст для глобального стану

Дуже часто useReducer комбінують із useContext, щоб зробити
глобальний стан без Redux / Zustand:

javascript
const StoreContext = createContext(); function StoreProvider({ children }) { const [state, dispatch] = useReducer(reducer, initialState); return <StoreContext.Provider value={{ state, dispatch }}>{children}</StoreContext.Provider>; }

Це міні-Redux прямо в React - чисто, передбачувано і без зовнішніх залежностей.

Коли НЕ потрібен useReducer

ВипадокКраще використовувати
Просте значення стану (boolean, число, рядок)useState
Незалежні станиДекілька useState
Логіка коротка і очевиднаuseState простіший і читабельніший
Немає різних «типів дій»useReducer надлишковий

Приклад порівняння

З useState

javascript
const [count, setCount] = useState(0); const [step, setStep] = useState(1); const increment = () => setCount(prev => prev + step);

Просто і читабельно - ідеально, якщо логіка проста.

З useReducer

javascript
const [state, dispatch] = useReducer(reducer, { count: 0, step: 1 }); function reducer(state, action) { switch (action.type) { case "increment": return { ...state, count: state.count + state.step }; case "setStep": return { ...state, step: action.payload }; default: return state; } }

Зручніше, якщо логіка розширюється - наприклад, з'являться decrement, reset, double тощо.

Підсумок

КритерійuseStateuseReducer
Проста логікаТакНі
Складні взаємозв'язкиНіТак
Багато типів змінНіТак
Централізація логікиНіТак
Легкість написанняТактрохи більше коду
Глобальний стан (через контекст)можливоідеально

Головне правило:

Використовуй useState для простих станів,
а useReducer - коли логіка керування станом стає «міні-бізнес-логікою».

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.