[TIL]React/Typescript Recoil과 framerMotion을 활용한 Timer만들기

ohoho·2024년 11월 3일

슬기로운스터디

목록 보기
40/54

오늘 공부한것 & 기억할 내용

Recoil과 FramerMotion을 활용하여 Timer를 만들었다.
조건 - Round가 4회가 되면 1Goal이 되어야한다.

  1. atom.ts
import { atom } from 'recoil';

interface ITimeData {
  time: number | null;
  isActive: boolean;
  round: number;
  goal: number;
}
export const TimeData = atom<ITimeData>({
  key: 'timeData',
  default: {
    time: null,
    isActive: false,
    round: 0,
    goal: 0,
  },
});
  1. Timer.tsx
const initialTime: number = 12;
const intervalRef = useRef<NodeJS.Timeout | null>(null);
const [{ time, isActive, round, goal }, setTimer] = useRecoilState(TimeData);
//초기화
const resetTimer = () => {
  //clearInterval의 매개변수에는 null이 없다.(그래서 if문 빼면 오류남)
  //clearInterval값이 null일 수 있기에 null이 아닐때만 실행하도록 if문 사용
  if (intervalRef.current) {
    clearInterval(intervalRef.current);
  }
  setTimer((pre) => ({
    ...pre,
    time: initialTime,
    isActive: false,
    round: 0,
    goal: 0,
  }));
};
//버튼(재생, 일시정지)
const toggleTimer = () => {
  setTimer((pre) => ({ ...pre, isActive: !pre.isActive }));
};

useEffect(() => {
  if (time === null) {
    setTimer((pre) => ({ ...pre, time: initialTime, isActive: false }));
    return; // time이 null일 경우 초기화
  }
  if (isActive && time > 0) {
    intervalRef.current = setInterval(() => {
      setTimer((pre) => ({
        ...pre,
        time: pre.time ? pre.time - 1 : 0,
      }));
    }, 1000);
  } else if (time === 0) {
    //타이머가 끝났을때 0 이 되었을때 실행될 코드작성
    setTimer((pre) => ({
      ...pre,
      time: initialTime,
      isActive: false,
      round: (pre.round + 1) % 4,
      goal: pre.goal + Math.floor((pre.round + 1) / 4),
    }));
  }
  return () => {
    if (intervalRef.current) {
      clearInterval(intervalRef.current);
    }
  };
}, [isActive, time]);

배운점 & 느낀점

recoil을 사용하여 Timer시간을 관리하는게 어떻게 해야할지 감이 잡히지 않아서 우선 한 파일에 다 만들어 본 다음 어느정도 윤곽이 잡혔을때 파일을 서로 분리하였다. 그리고 버튼 2개를 만들었어야 했을때 나는 버튼 2개를 각각 만들었는데 지피티에게 코드 개선을 요구했을때 isActive값으로 삼항연산자를 만들어 텍스트만 변경되도록 개선을 요구한게 인상이 깊었다.
recoil을 사용해보며 selector도 사용해봤다가 다시 지웠다가 우여곡절이 많았는데 많이 연습해봐야할거같다.
그리고 FramerMotion을 사용한 애니메이션 기능은 정말 최고인거 같다.
간단한 코드 몇개로 애니메이션 구현이 가능하니 안쓸 이유가 없다.

0개의 댓글