본문 바로가기
Study/React

Next.js + TypeScript ) 스크롤 내릴 시에 특정 컴포넌트 숨기기

by JongIk 2022. 7. 15.
반응형

스크롤시 상단 메뉴바 숨기기

작동화면

Code

NavBar.tsx

import { useScrollDirection } from "./useScrollDirection";
import styled from "styled-components";

const Header = styled.div`
  position: sticky;
  height: 3rem;
  transition-property: all;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  transition-duration: 500ms;
`;

const HeaderDown = styled.div`
  top: -3rem;
`;

const NavBar = () => {
  const scrollDirection = useScrollDirection();

  return (
    <>
      {scrollDirection === "down" && (
        <HeaderDown>
          // ...
        </HeaderDown>
      )}
      {scrollDirection !== "down" && (
        <Header>
            //...
        </Header>
      )}
    </>
  );
};

export default NavBar;

useScrollDirection.tsx

import { useEffect, useState } from "react";

export function useScrollDirection() {
  const [scrollDirection, setScrollDirection] = useState("");

  useEffect(() => {
    let lastScrollY = window.pageYOffset;

    const updateScrollDirection = () => {
      const scrollY = window.pageYOffset;
      const direction = scrollY > lastScrollY ? "down" : "up";
      if (
        direction !== scrollDirection &&
        (scrollY - lastScrollY > 10 || scrollY - lastScrollY < -10)
      ) {
        setScrollDirection(direction);
      }
      lastScrollY = scrollY > 0 ? scrollY : 0;
    };
    window.addEventListener("scroll", updateScrollDirection); // add event listener
    return () => {
      window.removeEventListener("scroll", updateScrollDirection); // clean up
    };
  }, [scrollDirection]);

  return scrollDirection;
}

RootComponent.tsx

import NavBar from "../components/navbar/NavBar";

const HideNavBar = () => {
  return (
    <>
      <NavBar />
      <div>
        <h1>상단 메뉴바 숨기기</h1>
        {Array.from({ length: 60 }).map(function (u, i) {
          return (
            <p key={i}>
              스크롤을 내릴때는 메뉴바가 사라지고 스크롤을 올릴때는 메뉴바가
              보입니다.
            </p>
          );
        })}
      </div>
    </>
  );
};

export default HideNavBar;
반응형

댓글