Change URL on scroll (React/Next)

Viewed 634

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!

0 Answers
Related