포스팅 이어서 하기 전 개념정리
useRef란
Hooks의 함수 중 하나로, DOM에 직접적으로 접근할 때 사용한다. (element.current) state가 바뀌거나, 어떤 이슈가 발생해도 리렌더링이 되지 않는다. JS에서 돔에 직접적으로 접근해 무언가를 처리 할 event를 사용할 때 useRef를 많이 사용한다.
- custom hook 생성
DOM에 직접 접근하는 useRef만들기 -> 애니메이션에 필요한 변수 타입 체크 -> useEffect를 사용해 DOM에서 처리할 코드 작성 => return값으로 ref, style- return값을 ref,style로 지정하면 spread operator로 따로 메서드로 넣지 않아도됨!
//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 조건문
- 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 }
};
};
//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값으로 처리해야 할 것 같은데 머리가 아픔 ^^;;
참조 / 출처