본문 바로가기
  • 사람은 무언가를 배울 필요가 있을때가 되서야 비로소 배우게 된다.
React

useRef - scroll이벤트처리!

by YoHaYo 2023. 12. 27.
728x90
반응형
  • console.log로 출력되는건 랜더링과 아무상관없음. useState사용X
  • 클래스명이 바뀌는것 또한 랜더링과 상관없음. useState사용X
  • 이런것들은 useEffect나 useRef를 써서 해결하기 !
/* 
  <useRef를 사용한 scrollSPY 기능구현>
  - console.log로 출력되는건 랜더링과 아무상관없음. useState사용X
  - 클래스명이 바뀌는것 또한 랜더링과 상관없음. useState사용X
  - 이런것들은 useEffect와 useRef를 써서 해결하기 ! 
*/
import React, { useRef, useEffect, useState } from 'react';

const ScrollPositionComponent = () => {
    const targetRef = useRef(null); 
    const [mytext, setMytext] = useState("Scroll Position Tracking")

    const handleScroll = () => {
        /*  A or B식. A가 참이면 B까지 안읽고 A 출력. and 식보다 훨씬 빠름 ! 
        scrollY, pageYOffset : 브라우저 환경에 따라 변수가 달라서 이렇게 배반선택으로 쓴다 ! 
        scrollY가 최신브라우저, pageYOffset이 구브라우저 변수임. 그래서 scrollY를 앞에 쓴다. 
        ※ window.scrollY : 얼마나 스크롤됬는지를 보여주는 변수
        */
        const scrollPosition = window.scrollY || window.pageYOffset; 

        // targetRef.current로 current까지 접근해야사용가능. 이건 그냥 문법이라 외우는영역.
        // getBoundingClientRect().top은 해당 요소의 상단 경계가 뷰포트의 상단에서 얼마나 떨어져 있는지를 나타냅니다. 이 값은 픽셀로 반환됩니다.        
        const targetTop = targetRef.current.getBoundingClientRect().top;  
        // const targetTop = targetRef.current.offsetTop

        if (targetTop < scrollPosition) {
            console.log(`뷰포트 상단부터의 거리 : ${targetTop}px`)
            targetRef.current.style.backgroundColor = "red";
            targetRef.current.style.color = "blue";
            setMytext("Scroll Changed !")
        } else {
            console.log(`스크롤값 : ${scrollPosition}px`)
            targetRef.current.style.backgroundColor = "white";
            targetRef.current.style.color = "black";
            setMytext("Scroll Position Tracking")
        }
    };

    /* 안전장치식. 
    targetRef가 지정되어야 실행될 수 있게 하는 식! 
    숙련자의 기법. */
    useEffect(() => {
      /* useEffect에서 scroll과 setInterval일때 return으로 청소하는것에 유의하자!
        scroll과 setInterval같이 랜더링이 무지막지하게 일어나는 경우 아예 이벤트 자체를 삭제해서
        메모리에 부하를 주는것을 막아야한다. 
        즉, scroll과 setInterval를 사용하면 useEffect에서 꼭 청소를 해주자 !
      */

        const targetElement = targetRef.current;
        
        if (targetElement) {
            window.addEventListener('scroll', handleScroll);
            console.log("scroll 이벤트 작동중")
            console.log(targetElement)
        }

        // useEffect return 정리 잘하기.
        // handleScroll이 필요없어지는 상황이 되면 삭제하는식. 지금은 조건이 지정안되서 적용안됨. 
        return () => {
            if (targetElement) {
                window.removeEventListener('scroll', handleScroll);
                console.log("scroll 이벤트 삭제")
            }
        };
    }, []); // [] : 한 번만 실행되고, 컴포넌트가 마운트될 때만 작동합니다.

    return (
        <div className='scrolltarget' ref={targetRef} style={{ border: '1px solid #ccc' }}>
            <h2>{mytext}</h2>
            <div style={{ height: '1000px' }}>Scroll down to see the effect</div>
        </div>
    );
};

export default ScrollPositionComponent;
반응형

'React' 카테고리의 다른 글

useMemo vs useCallback  (0) 2023.12.28
useRef - split로 데이터 띄어쓰기  (1) 2023.12.27
useEffect 란?  (1) 2023.12.21
컴포넌트란?  (0) 2023.12.18
리액트-탭메뉴 구현하기  (0) 2023.12.18

댓글