- useEffect와 setInterval을 사용하여 timer를 만들 수 있다.
import { useEffect, useState } from "react";
const getSeconds = (time) => {
const seconds = Number(time % 60);
if(seconds < 10) {
return "0" + String(seconds);
} else {
return String(seconds);
}
}
const Timer = () => {
const [time, setTime] = useState(300); // 남은 시간 (단위: 초)
useEffect(() => {
const timer = setInterval(() => {
setTime((prev) => prev - 1);
}, 1000);
return () => clearInterval(timer);
}, []);
return (
<div>
<h1>남은 시간</h1>
<div>
<span>{parseInt(time / 60)}</span>
<span> : </span>
<span>{getSeconds(time)}</span>
</div>
</div>
);
}
export default Timer;
위의 코드의 문제점은 시간이 음수가 되어도 멈추지 않는 것이다.
즉, clearInterval이 제대로 작동하고 있지 않다.
import { useEffect, useState } from "react";
const getSeconds = (time) => {
const seconds = Number(time % 60);
if(seconds < 10) {
return "0" + String(seconds);
} else {
return String(seconds);
}
}
const Timer = () => {
const [time, setTime] = useState(300); // 남은 시간 (단위: 초)
useEffect(() => {
const timer = setInterval(() => {
setTime((prev) => prev - 1);
}, 1000);
return () => clearInterval(timer);
}, [time]);
return (
<div>
<h1>남은 시간</h1>
<div>
<span>{parseInt(time / 60)}</span>
<span> : </span>
<span>{getSeconds(time)}</span>
</div>
</div>
);
}
export default Timer;
문제점은 useEffect의 deps에 time을 넣어주지 않은 것이다.
time을 변수에 제대로 넣어주면, 타이머가 제대로 동작함을 알 수 있다.
위와 같이 리액트에서 타이머를 만들 수 있다.
추가적으로 useEffect를 사용하여 time이 0보다 작아졌을 때, 이벤트를 발생시킬 수도 있다.
useEffect(() => {
if(time < 0) {
alert("Time OVER!");
}
}, [time]);