Два правила:
- Хуки викликають лише на верхньому рівні компонента чи власного хука: не в умовах, циклах, вкладених функціях, після раннього
return. - Хуки викликають лише з функціональних компонентів і власних хуків, не зі звичайних функцій чи класів.
Чому: React не знає імен ваших станів. Він зберігає стан компонента як список і зіставляє виклики хуків з елементами списку за порядком: перший useState - перший елемент, другий - другий. Якщо на одному рендері виклик пропустили через умову, усі наступні хуки «з'їдуть» на чужі значення.
// Неправильно
if (isLoggedIn) {
const [name, setName] = useState('');
}
const [theme, setTheme] = useState('light'); // візьме стан name, якщо умова змінилася
// Правильно: умова всередині, хук - завжди
const [name, setName] = useState('');
const displayName = isLoggedIn ? name : 'Гість';
Як не помилитися: плагін eslint-plugin-react-hooks перевіряє обидва правила й залежності useEffect. Його варто тримати увімкненим завжди.
Виняток: хук use (React 19) можна викликати в умовах і циклах - він читає Promise чи контекст і не зберігає стан у списку.