REACT_HOOKS useRef사용해서 fade-in /out 애니메이션 만들기

포스팅 이어서 하기 전 개념정리
useRef란
Hooks의 함수 중 하나로, DOM에 직접적으로 접근할 때 사용한다. (element.current) state가 바뀌거나, 어떤 이슈가 발생해도 리렌더링이 되지 않는다. JS에서 돔에 직접적으로 접근해 무언가를 처리 할 event를 사용할 때 useRef를 많이 사용한다.

애니메이션을 직접적으로 사용할 때

  • custom hook 생성
    DOM에 직접 접근하는 useRef만들기 -> 애니메이션에 필요한 변수 타입 체크 -> useEffect를 사용해 DOM에서 처리할 코드 작성 => return값으로 ref, style
  • return값을 ref,style로 지정하면 spread operator로 따로 메서드로 넣지 않아도됨!

custom hook 생성

//useScrollFadeIn.jsx
import { useEffect, useRef } from "react";

const useFadeIn =  (duration,delay) =>{
  const element= useRef();
  //element 접근 useRef
  if(typeof duration!== 'number' && typeof delay!== 'number' ) return;
  //type check
  useEffect(() => {
    if(element.current){
      const {current}= element;
      current.style.transition= `opacity ${duration}s ${delay}s`;
      current.style.opacity= 1;
    }
  },[duration,delay])
  //접근했을 때 opacity사용해서 애니메이션 효과
  //duration,delay가 변경될때마다 렌더링
  return {
    ref:element,
    style:{opacity:0}
  }
}

export default useFadeIn;
//MainPage.jsx
import useFadeIn from "./useScrollFadeIn";
export default function MainPage(){
const titleFadeIn= useFadeIn(2,1);
 return <div>
    <h2 {...titleFadeIn} >Testing Scroll Animation Using useRef</h2>
  </div>
}

React 읽는 순서
1. MainPage useFadeIn(2,1) 읽기
2. useFadeIn return
3. MainPage render
4. useFadeIn useEffect
5. useEffect 조건문

Fade-out 코드

  • setTimeout으로 opacity 0 으로 만들기
//useFadeIn.jsx
const useFadeIn = (duration, delay) => {
  const element = useRef();
  if (typeof duration !== "number" && typeof delay !== "number") return;
  useEffect(() => {
    if (element.current) {
      console.log('active1')
      const { current } = element;
      current.style.transition = `opacity ${duration}s ${delay}s`;
      current.style.opacity = 1;
      setTimeout(() => {
        current.style.opacity = 0;
      },parseInt(`${duration}000`))
      //duration실행 뒤 opacity0으로 만들고, parseInt로 문자열 숫자로 바꾸기
    }
  }, [duration, delay]);
  return {
    ref: element,
    style: { opacity: 0 }
  };
};

scroll위치에 도달했을 때 animation시작

//useScrollFadeIn.jsx
import { useEffect, useRef } from "react";
const useFadeIn = (duration, delay) => {
  if (typeof duration !== "number" && typeof delay !== "number") return;
  //타입체크
  const element = useRef();
  const fadeAnimation = () => {
    const { current } = element;
    current.style.transition = `opacity ${duration}s ${delay}s`;
    current.style.opacity = 1;
    setTimeout(() => {
      current.style.opacity = 0;
    }, parseInt(`${duration}000`));
  };
  //fadeIn - fadeOut 함수
  useEffect(() => {
    const elemPosition = element.current.clientTop;
    window.addEventListener("scroll", () => {
      const currentScroll = window.pageYOffset;
      if (currentScroll >= elemPosition && element.current) {
        fadeAnimation();
        //스크롤 위치 element보다 아래있고, element가 undefined가 아닐때 애니메이션 실행
      }
    });
  }, []);

  return {
    ref: element,
    style: { opacity: 0 }
  };
};

export default useFadeIn;

문제가 있음.. 애니메이션 무한반복됨.. state값으로 처리해야 할 것 같은데 머리가 아픔 ^^;;

참조 / 출처

좋은 웹페이지 즐겨찾기