Trzeba by użyć pętli. Zrobiłem zmiany w ciemno i musiałem odwrócić warunek więc nie wiem czy zadziała. Jeśli nie zadziała może łatwiej będzie odwrócić kolejność elementów w tablicy lub zmienić nieco warunek.
Co do samego kodu warto aby funkcja handleScroll była w środku useEffect dzięki temu funkcja będzie stworzona tylko gdy będzie użyta. Obecnie funkcja tworzy się na nowo przy każdym renderowaniu komponentów.
Dodatkowy problem to czas wykonywania getBoundingClientRect ta funkcja aby zwrócić wynik musi obliczyć wszystko na nowo i ponownie wyrenderować stronę. Informacje o pozycjach są tracone po skończeniu renderowania. Powinniśmy jej unikać. Warto zastanowić się czy przepisanie tego na https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver nie było by dobrym pomysłem.
Ewentualnie można się zastanowić nad zapisywaniem w useRef() wszystkich wartości raz i podczas scrolla nie wywoływać getBoundingClientRect za każdym razem. Można też pokusić się o jakiś debounceTime dla handlera obsługującego event scrolla.
const [activeSection, setActiveSection] = useState("about");
useEffect(() => {
const handleScroll = () => {
const elementsId = [
"about",
"technologies",
"experience",
"projects",
];
const elements = elementsId.map(id => document.getElementById(id))
for (let i = 0; i < elements.length; i++) {
const element = elements[i];
const rect = element.getBoundingClientRect();
if (!(rect.height / 2 - 200 <= rect.y * -1)) {
setActiveSection(elementsId[i]);
break;
}
}
}
window.addEventListener("scroll", handleScroll);
return () => {
window.removeEventListener("scroll", handleScroll);
};
}, []);