I'm working on a React/Next form which displays 32 questions on a single page. Since I need to know which question is active, I thought about using the scroll to get it.
First, I created a useScrollPosition hook to track the current scrollPosition on the viewport:
**useScrollPosition.ts**
export const useScrollPosition = () => {
const [scrollPosition, setSrollPosition] = useState(0);
const handleScroll = () => {
const position = window.pageYOffset;
setSrollPosition(position);
};
useEffect(() => {
window.addEventListener('scroll', handleScroll, { passive: true });
return () => {
window.removeEventListener('scroll', handleScroll);
};
}, []);
return {
scrollPosition
};
};
Then, added a Ref to my questions with a unique id:
**Question.tsx**
const questionScrollRef = useRef<HTMLDivElement>();
...
<div id={`question-${name}`} ref={questionScrollRef}></div>
<Question />
Finally, on the Form.tsx stored all the Refs's offsetTops into a scrollRefs array, so I could iterate over them, compare to the current scrollPosition and change the route onScroll:
**Form.tsx**
...
const scrollRefs = [];
if (typeof window !== 'undefined') {
sectionQuestions.map(section => (
section.questions.map((question) => (
scrollRefs.push(document.getElementById(`question-${question.name}`)?.offsetTop)
))
));
}
for (let i = 0; i < scrollRefs.length; i++) {
if (_.inRange(scrollPosition, scrollRefs[i], scrollRefs[i + 1])) {
useEffect(() => {
router.push(`/?question=${i + 1}`)
}, [])
}
}
The issue is that this loop only changes to route to the last question (number 32), ignoring the previous 31 questions. Any thoughts on how to fix it? Thanks!