useState хранит локальное состояние. Обновляйте его иммутабельно — React сравнивает ссылки.
useEffect — для синхронизации с внешним миром (DOM, сеть, подписки). Не используйте его для вычисляемых значений — считайте при рендере.
Правила хуков: только на верхнем уровне, только в React-функциях. Это сохраняет порядок вызовов между рендерами.