[Next.js] setInterval을 사용한 타이머 구현

정다롱·2024년 11월 1일

내일배움캠프 TIL

목록 보기
38/39

🖥️ supabase, setInterval 타이머 기능 구현하기

최종 프로젝트에 들어가는 타이머 기능을 구현하기 위해 useEffect, setInterval을 사용했다.

✅ 간단 설명

useEffect

  • 컴포넌트가 렌더링 완료된 시점에서 실행되는 리액트 훅.
  • 의존성 배열에 값이 있을 경우 해당 값이 변경되었을 때만 실행됨.
  • 의존성 배열이 빈 배열일 경우 컴포넌트 최초 렌더링 시에만 실행됨.
  • useEffect 안에 실행될 interval을 넣고 타이머의 재생 상태가 변경될 때마다 실행되도록 설정함

interval

  • 지정된 시간마다 특정 로직을 반복하게 하는 함수
  • 타이머가 재생 상태일 때 1초마다 경과시간을 계산하는 함수를 넣어 UI에 표시되도록 설정함.

supabase 테이블 구조

  • user, study id 저장 => 어디 스터디인지 누구 타이머인지 확인
  • date => 오늘의 타이머인지 확인
  • last_start, last_paused => 마지막 시작, 정지 시간 확인 (경과시간 계산용)
  • accumulated_time => 누적시간

✅ 주요 로직

  1. 실제로 타이머가 1초씩 들어나도록 ui 반영
    const timerInterval = setInterval(() => {
      const totalElapsed = calculateElapsedTime(
        timerState.last_start,
        timerState.accumulated_time,
      );
      setTime(totalElapsed);
    }, 1000);
  • 해당 interval은 타이머가 재생중일 때만 실행됨.
  • 1초마다 경과시간을 재계산하여 time 상태를 set하고 있음 => 1초마다 ui 변경

2. 캘린더에 등록된 시간이 지나면 자동으로 정지
      const timeCheckInterval = setInterval(() => {
      const isValid = checkTimeRange(currentSchedule);
      setIsWithinTimeRange(isValid);
      if (!isValid) {
        updateTimerState("pause");
      }
    }, 1000);
  • 마찬가지로 타이머가 재생중일 때만 실행됨.
  • 1초마다 현재 시간과 캘린더에 등록된 시간을 비교하여 지금이 스터디 시간인지 확인
  • 만약 시간 범위를 벗어나면 즉시 타이머 종료

3. 경과 시간 계산 함수
  const calculateElapsedTime = (
    lastStartTime: string | null,
    accumulatedTime: number,
  ) => {
    if (!lastStartTime) return accumulatedTime;

    // UTC 시간을 기준으로 시간차 계산
    const start = Date.parse(lastStartTime);
    const now = Date.now();
    return accumulatedTime + Math.floor((now - start) / 1000);
  };
  • 계산이 필요한 시점에(첫 렌더링 타이머 세팅, interval 계산) 호출하여 사용.
  • 시작 시간, 누적 시간을 인자로 받음
  • 시작 시간이 없을 때 => 일시정지 상태일때 지금까지 누적 시간을 반환
  • 시작 시간이 있을 때 => 재생 상태일때 누적시간 + (현재-시작)(경과시간) 계산하여 반환

✅ 결과!

0개의 댓글