Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «useReducer() проти useState()». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**`useReducer()`** варто використовувати замість `useState()`, коли логіка оновлення складна або багатоступенева, стан має багато взаємопов'язаних даних і потрібна зрозуміла структура «дій» (actions) - на відміну від `useState`, який пасує для простого, незалежного значення стану. **Ключове:** редьюсер робить стан детермінованим - та сама дія завжди дає той самий новий стан.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## Основна відмінність | Хук | Для чого | |---|---| | `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` тощо. ## Підсумок | Критерій | `useState` | `useReducer` | |---|---|---| | Проста логіка | Так | Ні | | Складні взаємозв'язки | Ні | Так | | Багато типів змін | Ні | Так | | Централізація логіки | Ні | Так | | Легкість написання | Так | трохи більше коду | | Глобальний стан (через контекст) | можливо | ідеально | --- **Головне правило:** > Використовуй `useState` для простих станів, > а `useReducer` - коли логіка керування станом стає «міні-бізнес-логікою».Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.