[nextjs] 페이지 이동하면서 원하는 위치로 스크롤 하기

해달·2022년 12월 22일

개요

페이지 이동하면서
A를 누르면 A에 관한 내용이 있는 곳,
B를 누르면 B에 관한 내용이 있는 곳으로 각각 원하는 위치로 스크롤 되는 기능을 구현해야했다.

어떻게 구현할지 고민하다가 클릭 시 query에 이동해야 하는 위치 값을 가지고 페이지 이동하도록 했다.


이동할 때 쿼리달고가는 코드

이동하면서 클릭 된 값을 가지고 option1 쿼리값은 가지지만
유저에게 노출시키지 않도록 as params 에 표시 될 url을 기재해준다.

as : masking되어 브라우저의 URL 바에 보여질 주소
as는 간단하게 Route Masking 으로 표현할 수 있다.

//code
  onClick={() => {
    router.push(
      { pathname: `/service`, query: { option:  'option1' } }, 
      '/service');
  }}
  1. 각 내용이 보여질 컴포넌트들 위에 divider를 보여주고 ref 걸어준다.
  2. ref의 scroll 위치를 구해와서 scrollTo로 이동시켜주는 함수를 하나 만들어준다.
  3. useEffect로 ref값이 변경될 때 함수를 실행시킨다.
const Service = ({ option }: P) => {
  const option1Ref = useRef<HTMLDivElement | null>(null);
  const option2Ref = useRef<HTMLDivElement | null>(null);

  const handleServiceFocus = (option: 'option1' | 'option2') => {
    const option1ScrollY = option1Ref.current
      ? option1Ref.current.getBoundingClientRect().top - 60
      : 0;


    const contentScrollY = {
      option1: option1ScrollY,
    };

    window.scrollTo({
      behavior: 'smooth',
      left: 0,
      top: contentScrollY[option],
    });
  };

  useEffect(() => {
    if (option) {
      handleServiceFocus(option);
    }
  }, [option1Ref]);

  return (
    <FlexColumnBox>
      <Test1 />
      <CustomDivider
        height={8}
        color={`grey100`}
        verticalPadding={24}
        ref={option1Ref}
      />
      <Test2 />
      <CustomDivider
        height={8}
        color={`grey100`}
        verticalPadding={24}
        ref={option2Ref}
      />
    </FlexColumnBox>
  );
};

query를 사용하지 않고 스크롤 시킬 수 있는 방법을 사용하려했으나,
클릭되는 값에 맞추어 ref를 사용해 element의 정확한 위치 값을 얻어오도록 작성했다.
초반에는 구현방식이 감이 잡히지 않아서 꽤 고생했지만 원하는대로 구현할 수 있었다

0개의 댓글