Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Правила хуків». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)Хуки в React підпорядковуються двом головним правилам: викликати їх тільки на верхньому рівні (завжди в одному й тому самому порядку при кожному рендері) і тільки у функціональних компонентах або кастомних хуках. **Ключове:** React визначає, який стан якому хуку належить, за порядком виклику - якщо порядок зміниться (наприклад, через `if`), React "переплутає" стани.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## Два головні правила хуків ### 1. **Викликай хуки тільки на верхньому рівні** > Не викликати хуки всередині умов, циклів або вкладених функцій. > Хуки повинні викликатися **завжди в одному й тому самому порядку** при кожному рендері. ```javascript // Погано if (isVisible) { const [count, setCount] = useState(0); // порушення правила! } // Добре const [count, setCount] = useState(0); if (isVisible) { // просто використовуємо count } ``` **Чому це так важливо:** React визначає, **який стан якому хуку належить**, за **порядком виклику**. Якщо порядок зміниться (наприклад, через `if`), React "переплутає" стани. --- ### 2. **Викликай хуки тільки у функціональних компонентах або кастомних хуках** > Не можна викликати хуки поза компонентом. > Хуки можна викликати: > > - всередині **функціонального компонента** > - або всередині **кастомного хука** (функції, ім'я якої починається з `use`) ```javascript // Погано useState(); // поза компонентом - помилка // Добре function MyComponent() { const [value, setValue] = useState(0); } // Добре (кастомний хук) function useCounter() { const [count, setCount] = useState(0); return [count, setCount]; } ``` --- ## Додаткові хороші практики ### 3. **Ім'я власного хука повинне починатися з** `use` Це потрібно, щоб React розумів, що це хук (наприклад, для лінтингу). ```javascript function useLocalStorage(key, initialValue) { ... } // так function localStorageHook(key, initialValue) { ... } // ні ``` --- ### 4. **Передавай залежності правильно в** `useEffect`**,** `useMemo`**,** `useCallback` ```javascript useEffect(() => { fetchData(id); }, [id]); // id - залежність ``` Якщо пропустити залежність, код може використовувати **застарілі значення** і поводитися непередбачувано. --- ### 5. **Не викликати хуки всередині звичайних JS-функцій** Якщо потрібно перевикористати логіку - зроби **кастомний хук**: ```javascript // Погано function fetchUser() { const [user, setUser] = useState(null); // не можна } // Добре function useUser() { const [user, setUser] = useState(null); return user; } ``` --- ## React допомагає дотримуватися цих правил React постачається з лінтером: `eslint-plugin-react-hooks` Він автоматично перевіряє: - порядок виклику хуків, - коректність залежностей у `useEffect`. ```javascript npm install eslint-plugin-react-hooks --save-dev ``` У `.eslintrc`: ```javascript { "plugins": ["react-hooks"], "rules": { "react-hooks/rules-of-hooks": "error", "react-hooks/exhaustive-deps": "warn" } } ``` --- ## Коротке резюме | Правило | Навіщо | |---|---| | Хуки викликаються тільки на верхньому рівні | Щоб порядок викликів не змінювався | | Хуки викликаються тільки в компонентах або хуках | Щоб React міг відстежувати стан | | Кастомні хуки починаються з `use` | Для читабельності і перевірки лінтером | | Коректні залежності в `useEffect`/`useMemo`/`useCallback` | Щоб не використовувати застарілі значення | | Використовуй ESLint-правила | Щоб React сам підказував помилки |Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.