Next.js 13 Full page 구현해보기

버건디·2023년 8월 31일
0

Next.js

목록 보기
46/52
post-thumbnail
post-custom-banner

- 완성 화면

- 콘텐츠 코드

"use client";

import { useEffect, useRef, useState } from "react";

export default function Plans() {
  const [currentPageNum, setCurrentPageNum] = useState<number>(0); // 0-based indexing
  const maxPageNum = 4; // 또는 원하는 최대 페이지 수
  const pageRefs = useRef<HTMLDivElement[]>(Array(maxPageNum).fill(null));

  const handlePageChange = () => {
    let scroll = window.scrollY;
    for (let i = 0; i < 4; i++) {
      // pageRefs.current[i]가 null이 아닌지 확인
      if (pageRefs.current[i]) {
        if (
          scroll > pageRefs.current[i].offsetTop - window.outerHeight / 3 &&
          scroll <
            pageRefs.current[i].offsetTop -
              window.outerHeight / 3 +
              pageRefs.current[i].offsetHeight
        ) {
          setCurrentPageNum(i);
          break;
        }
      }
    }
  };

  const handlePointClick = (pageNum: number) => {
    window.scrollTo({
      top: pageRefs.current[pageNum].offsetTop,
      behavior: "smooth",
    });
  };

  useEffect(() => {
    window.addEventListener("scroll", handlePageChange);
    return () => {
      window.removeEventListener("scroll", handlePageChange);
    };
  }, []);

  return (
    <>
      <Content pageNum={1} pageRefs={pageRefs} />
      <Content pageNum={2} pageRefs={pageRefs} />
      <Content pageNum={3} pageRefs={pageRefs} />
      <Button
        handlePointClick={handlePointClick}
        currentPageNum={currentPageNum}
      />
    </>
  );
}

원래 컨텐츠들을 객체로 관리해서 map 함수를 통해 뿌려주면 되지만,

컨텐츠들의 내용들이 다 달라서 일단 각각 컨텐츠 컴포넌트들을 만들어주었다.

비슷한 형식이라면 객체로 묶어줘서 map 함수로 뿌려주는것이 낫다.

profile
https://brgndy.me/ 로 옮기는 중입니다 :)
post-custom-banner

0개의 댓글