[nextjs] nextjs13에서 scroll Indicator적용

개잼·2023년 7월 31일
0
post-custom-banner

인사

안녕하세요.
이번에는 nextjs 13 version으로 scroll Indicator를 적용하는 것
에 대해 알아보겠습니다.


Nextjs 13??

nextjs가 13 version으로 Update 됨에 따라 client component와 server component로 나눠쓰는 것에 대한 중요성이 강조되었습니다.
가령 useEffect, useState를 쓰기 위해선 client component에서 쓰지 않으면 error 발생하는 것처럼 말이죠.

하지만 무분별한 client component 생성은 nextjs13 version 사용에 대한 의미가 희미해진다고 생각하기 때문에 이를 적절하게 사용하는 것이 좋아 보입니다.
이에 따라 최소한의 client component 생성을 scroll indicator 적용을 예시로 보이려고 합니다.


1. Header.tsx

import Link from "next/link";
import IndicatorScroll from "./IndicatorScroll";

const Header:React.FC = () => {

    return (
        <nav className="sticky top-0">
            <div className="flex justify-between p-10 font-play shadow">
                <div>
                    <Link href="/">SangEok</Link>
                </div>
                <div>
                    <span className="px-5"><Link href="/post">Post</Link></span>
                    <span className="px-5"><Link href="/about">About</Link></span>
                </div>
            </div>
            <IndicatorScroll />
            
        </nav>
    )
}

export default Header;

  • sticky
    position을 sticky로 지정하여 header에 맞게 상단고정
    (sticky 사용 시, top, bottom, left, right 중 하나의 값을 필수로 사용해야 함. 여기서는 top : 0을 사용)

  • server component
    기본적으로 scroll indicator는 header에 붙어 있습니다.
    하지만 scroll indicator는 useEffect, useState를 사용해야 하므로 header.tsx와 같은 server component가 아닌 client component에서 따로 생성해줘야 합니다.
    여기서 nav tag의 모든 내용을 client component로 만들 수 있겠지만, 그렇지 않고 scroll indicator만 client component로 만들어줬습니다.
    (자세한 이유는 공식문서)


https://nextjs.org/docs/getting-started/react-essentials
참고 : nextjs 공식문서


2. IndicatorScroll.tsx

'use client'
import { useEffect, useState } from "react";

export default function Indicator() {
    const [completion, setCompletion] = useState(0);

    useEffect(()=>{
        const updateScrollCompleltion = () => {
            const currentProgress = window.scrollY;
            const scrollHeight = document.body.scrollHeight - window.innerHeight;
            if(scrollHeight) {
                setCompletion(
                    Number((currentProgress / scrollHeight).toFixed(2)) * 100
                )
            }
        }

        window.addEventListener('scroll', updateScrollCompleltion);

        return () => {
            window.removeEventListener('scroll', updateScrollCompleltion);
        }

    },[])

    return (
        <div>
            <span
                style={{ transform: `translateX(${completion-100}%)`}}
                className="absolute bg-yellow-400 h-1 w-full bottom-0"
            />
        </div>
    )
}
  • client component
    위에서 보시는 바와 같이 useEffect, useState를 사용하기 위해 가장 상단에 'use client'를 선언함.
    소스 내용을 보면 정말 scroll indicator만 client component로 나타낸 것을 볼 수 있음.

3. Result


이와 같이 일정 scroll이 내려감에 따라 header에서 scroll indicator가 잘 나타났음을 확인할 수 있다.

profile
천천히 나아가는 중
post-custom-banner

2개의 댓글

comment-user-thumbnail
2023년 7월 31일

좋은 정보 감사합니다

1개의 답글