본문 바로가기

리액트

React scroll시 css 변경하기

넷플릭스에 헤더 스크롤 시 변경되는 거 구현하기

Code


 import React, { useEffect, useRef, useState } from 'react'

export default function useScrollY() {
  // requestAnimationFrame 시스템이 프레임을 그릴 준비가 되면 애니메이션 프레임을 호출하여 웹을 원활하고 효율적으로 그려준다.
  const [open, setOpen] = useState(false)
  const topRef = useRef(null)

  useEffect(() => {
    const handleScroll = () => {
      if (topRef.current) {
        cancelAnimationFrame(topRef.current)
      }
      topRef.current = requestAnimationFrame(() => {
        const scrollY = window.scrollY
        if (scrollY > 0) {
          setOpen(true)
        } else {
          setOpen(false)
        }
      })
    }

    window.addEventListener('scroll', handleScroll)

    return () => {
      window.removeEventListener('scroll', handleScroll)
      if (topRef.current) {
        cancelAnimationFrame(topRef.current)
      }
    }
  }, [])

  return { open }
}
  
  • modal 열렸는지 안 열렸는지 상태를 저장하는 값과, ref로 특정 dom을 건드리거나 기억할 떄 사용 여기서는 requestAnimationFrame Id를 기억하기 위해 사용
    
         const [open, setOpen] = useState(false)
     	 const topRef = useRef(null)
         
  • useEffect hook으로 처음 렌더링 시 실행 cancelAnimationFrame()으로 중복 되지 않게 삭제 한다. requestAnimationFrame()을 사용하여 프레임을 최적화 해준다. scrolly 를 실행 했을 떄 0보다 크면은 보이고, 아니면 안 보인다.
    
        useEffect(() => {
        const handleScroll = () => {
          if (topRef.current) {
            cancelAnimationFrame(topRef.current)
          }
          topRef.current = requestAnimationFrame(() => {
            const scrollY = window.scrollY
            if (scrollY > 0) {
              setOpen(true)
            } else {
              setOpen(false)
            }
          })
        }
         
  • 이벤트리스너로 스크롤시 handleScroll()를 실행하고 최적화를 위해 스크롤을 하지 않는다면 지워준다.
    
          window.addEventListener('scroll', handleScroll)
    
        return () => {
          window.removeEventListener('scroll', handleScroll)
          if (topRef.current) {
            cancelAnimationFrame(topRef.current)
          }
        }
         

중요한 점

  • handleScroll이 useEffect 안에 정의되어 있지만, 그 이후에는 이벤트 리스너를 통해 실행됩니다.
    - `handleScroll` 함수는 `useEffect` 내에서 처음 한 번만 정의되고, 이후에는 `window.addEventListener('scroll', handleScroll)`을 통해 이벤트 리스너로 등록되어 스크롤 이벤트가 발생할 때마다 실행됩니다.
  • 의존성 배열에 handleScroll을 추가할 필요가 없는 이유는, handleScroll 함수 자체가 상태나 다른 값에 의존하지 않기 때문입니다.
    - `handleScroll`은 오로지 `scroll` 이벤트에 의해 실행되며, 그 내부에서 상태를 업데이트하지만, 다른 상태나 props에 의존하지 않습니다. 따라서 `useEffect`의 의존성 배열에 `handleScroll`을 추가할 필요가 없습니다.
  • handleScroll은 오로지 스크롤 이벤트에 의해 실행되며, 그 자체로 상태를 업데이트할 뿐입니다.
    - `handleScroll`은 스크롤 이벤트를 감지하고 그에 맞게 상태를 업데이트하는 역할만 하므로, 그 자체로 독립적으로 실행됩니다. 상태나 다른 값에 의존하지 않기 때문에, `useEffect`의 의존성 배열에 추가하지 않아도 정상적으로 동작합니다.

구현 화면

'리액트' 카테고리의 다른 글

React  (0) 2025.01.07
React-player 라이브러리  (0) 2024.12.31
React Potal Modal 구현하기  (3) 2024.12.31
React 캐로셀  (1) 2024.12.31
React 커스텀 Hook, await와 axios.all 활용법  (4) 2024.12.28