[React #1]custom hooks, count up animation component

Soozynn·2022년 6월 27일
0

React

목록 보기
1/4

면접 사전 과제를 진행하면서 정리를 하고 싶은 내용이 있어 정리해보고자 한다.
노마드코더 강의를 이전에 보면서 커스텀 훅을 어떤 식으로 만드는지는 알았으나 직접적으로 만들어본 경험은 없었는데 이번 과제에서 useFadeIn 훅을 만들어 보았다. fadeIn은 서서히 나타나게끔 하는 효과 명칭이다.

사전 과제에서는 시작되어지는 고정된 tranform 값이 있었고 fadeIn 효과가 컴포넌트 별로 지정되어 있어 이러한 커스텀 훅을 만들게 되었다.

// animation count up 구현
import { useEffect, useState } from "react";
import PropTypes from "prop-types";

// easeOutQuad는 카운트가 진행됨에 따라 느려지는 Easy-out 기능이다.
const easeOutQuad = (time) => time * (2 - time);
const frameDuration = 1000 / 60;

export default function CountUpAnimation({ children }) {
  const animationDuration = 1000;
  const countNumber = parseInt(children, 10);
  const [count, setCount] = useState(0);

  useEffect(() => {
    const totalFrames = Math.round(animationDuration / frameDuration);
    let frame = 0;

    const counter = setInterval(() => {
      frame++;
      const progress = easeOutQuad(frame / totalFrames);
      setCount(countNumber * progress);

      if (frame === totalFrames) {
        clearInterval(counter);
      }
    }, frameDuration);
  }, []);

  return Math.floor(count);
}

CountUpAnimation.propTypes = {
  children: PropTypes.string.isRequired,
};

위 코드는 카운트를 어떻게 DOM만을 이용해서 업 시켜줄 수 있을까 고민하다 발견한 오픈소스를 개량한 코드이다. 내가 참고한 링크는 링크에 첨부해두었다. 해당 부분에 대해서 더 깊이 있게 공부를 해보려고 한다.
또 컴포넌트가 아닌 useFadeIn과 같이 hooks로 만들어주어도 좋겠다고 생각하여 hook으로 변형한 코드도 추후에 올려보려고 한다.

easeOutQuad란?

과제를 진행하면서 현재 위에서 작성한 easeOutQuad는 너무 빠르게 동작하는 부분이 있어 개념을 살펴본 뒤 조금 더 수정을 거쳐주었다.

// react useFadeIn custom hooks 만들어보기
import { useEffect, useRef } from "react";
import PropTypes from "prop-types";

export default function useFadeIn(duration, delay) {
  const element = useRef();

// useEffect를 사용하여 컴포넌트가 마운트 된 후 아래 style이 입혀지도록 설정
  useEffect(() => {
    if (element.current) {
      const { current } = element;
      current.style.opacity = 1;
      current.style.transform = "translateY(0%)";
      current.style.transition = `all ${duration}ms ease-in-out ${delay}ms`;
    }
  }, []);
  
// 리턴되는 값은 처음 컴포넌트가 마운트 됐을 때의 원하는 style을 리턴시켜주었다.
  return {
    ref: element,
    style: { opacity: 0, transform: "translateY(10px)" },
  };
}

useFadeIn.propTypes = {
  duration: PropTypes.number.isRequired,
  delay: PropTypes.number.isRequired,
};

위 훅은 적용할 태그에 <ContentArticles {...fadeInTitle}>와 같이 태그 내부에 spread 문법을 사용하여 지정해주면 useFadeIn hooks의 효과를 입힐 수 있다.

0개의 댓글