HitGirl, и здесь не происходит размонтирования. Размонтирование - это когда компонент убирается из dom-дерева. Ты же сейчас пытаешься отследить этап в жизненном цикле компонента.
HitGirl, в комменте выше сказали - потому что юзэффект вызывается дважды. Скорее всего в строгом режиме и компонент рендерится дважды, деталей не знаю, не вникал. Но суть в том что так как изменения ты вносишь в самом юзэффекте, то при первом рендеринге фалс, при втором - тру. Можешь отключить стрикт мод (в index.js в него обернут компонент app) и второй лог пропадет. В теории останется только false, так как изменение рефа не должно тригерить ререндер. Либо если ты в функции onInputChanged изменяешь какой-либо стейт, то двойная запись останется, потому что это затригерит ререндер дочернего компонента.
HitGirl, первое - насколько я знаю реф имеет смысл если использовать его с dom-элементами. Посмотри примеры.
Дальше- в чем смысл const deferredInput = useDeferredValue(searchInput)? ты пробуешь отсрочить отправку запроса при вводе? тогда посмотри как реализуется debounce. Так твой запрос будет отправлен через установленное тобой время после того, как пользователь завершит ввод.
И да, конечно проще настроить условия, при которых будет делаться запрос, чем добавлять несколько хуков и изобретать велосипед. Каждый хук это ведь тоже определенная работа и выполнение логики для реакта. Не умножай сущности короче без причины.
потому что тебе нужно настроить именно vite для разработки. У него есть свой конфигурационный файл. Хотя в твоем случае наверное вебпак было бы проще использовать, если нужно просто собирать js/css. А в настройке пхп-фреймворка уже пропишешь тот путь, по которому сборщик собирает бандл.