я б попробовал через реф, через indow.innerHeight и getBoundingClientRect.bottom находил разность и если она больше либо равна нулю то выполнял функцию. если нужно выполнить 1 раз, то можно поставить флаг, который меняется при выполнении функции. можно попробовать через IntersectionObserver, но с ним я не работал, не подскажу