최종 프로젝트에 들어가는 타이머 기능을 구현하기 위해 useEffect, setInterval을 사용했다.
useEffect
- 컴포넌트가 렌더링 완료된 시점에서 실행되는 리액트 훅.
- 의존성 배열에 값이 있을 경우 해당 값이 변경되었을 때만 실행됨.
- 의존성 배열이 빈 배열일 경우 컴포넌트 최초 렌더링 시에만 실행됨.
- useEffect 안에 실행될 interval을 넣고 타이머의 재생 상태가 변경될 때마다 실행되도록 설정함
interval
- 지정된 시간마다 특정 로직을 반복하게 하는 함수
- 타이머가 재생 상태일 때 1초마다 경과시간을 계산하는 함수를 넣어 UI에 표시되도록 설정함.
supabase 테이블 구조
- user, study id 저장 => 어디 스터디인지 누구 타이머인지 확인
- date => 오늘의 타이머인지 확인
- last_start, last_paused => 마지막 시작, 정지 시간 확인 (경과시간 계산용)
- accumulated_time => 누적시간
const timerInterval = setInterval(() => {
const totalElapsed = calculateElapsedTime(
timerState.last_start,
timerState.accumulated_time,
);
setTime(totalElapsed);
}, 1000);
const timeCheckInterval = setInterval(() => {
const isValid = checkTimeRange(currentSchedule);
setIsWithinTimeRange(isValid);
if (!isValid) {
updateTimerState("pause");
}
}, 1000);
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);
};
