๋ชฉ์ฐจ
ํ๋ก์ ํธ์ ์ฝ์ ํ ์คํฑ์์น ๋ง๋ค์ด ๋์๋ค.
6์ด๋ฅผ ์ธ์ด๋ณด๋๋ฐ ์ด์ํ๊ฒ ์ฒด๊ฐ ์ 8์ด๋ ๋๋ ๊ฒ ๊ฐ์๋ค.
์ ์ด๊ฑฐ ์ด์ํ๋ฐ??
1. setInetval์ ํ์ฉํ ํ์ด๋จธ
1) ์์ฑ ์ฝ๋
๋ด๊ฐ ์์ฑํ ์ฝ๋๋ setInterval์ ์ด์ฉํ์ฌ ์ฃผ๊ธฐ์ ์ผ๋ก ์๊ฐstate๋ฅผ ์ฆ๊ฐ์ํค๋ ๋ฐฉ์์ด๋ค.
const [run, setRun] = useState(); //์คํฑ์์นstart์ํ
const [time, setTime] = useState(0); //์๊ฐstate
const intervalRef = useRef();
//์์์ํ ๊ฐ์ง
useEffect(()=>{
if(props.start){
setRun(true);
}
else{
clearInterval(intervalRef.current)
setRun(false);
}
},[props.start])
//์๊ฐ ์ฆ๊ฐ ๊ธฐ๋ฅ
useEffect(()=>{
if(run){
intervalRef.current = setInterval(() => {
setTime(val=>val+10);
},10);
}
},[run])
//์ผ์ ์๊ฐ ์ง๋๋ฉด stop & ๋ฐํ์ ์ ๋ณด ์ ์ฅ
useEffect(()=>{
if(time == props.stop*1000+1){
clearInterval(intervalRef.current)
setRun(false);
}
else{
props.setRunTime(time)
}
})
์ด ๋ฐฉ๋ฒ์ ์ด์ฉํ์์๋ ์ ํํ ์๊ฐ์ ๋ณด์ฅํ์ง ์๊ณ ๋ฐ๋ฆฌ๋ ํ์์ด ์ผ์ด๋ฌ๋ค.
2) ์ค๋ฅ์ ์์ธ
setTimeout๊ณผ setInterval์ Web API ์์ ๋ณ๋๋ก ์คํ๋๋ค.
๋ฐ๋ผ์ ๋น๋๊ธฐ ์์ ์ด ๊ฐ๋ฅํ ๊ฒ์ด๋ค. (์ฑ๊ธ์ค๋ ๋์์๋ ๋ถ๊ตฌํ๊ณ !)
ํ์ง๋ง, ๋ง๋ฅ๋จ๋ ธ๋ ๊ฒ์ฒ๋ผ ์๊ฐ ์ง์ฐ ํ์์ด ์ผ์ด๋ ์ ์๋ค.
์์ ๊ทธ๋ฆผ์ ์ฐธ๊ณ ํด setTimeout, setInterval์ ์ฒ๋ฆฌ๊ณผ์ ์ ์ดํด๋ณด์.
1. Web API์ setInetval์ ์ด์ฉํด ์ค์ ํ N ms์ ์๊ฐ์ด ์ง๋ ํ ์ฒ๋ฆฌ๋ฅผ ํ๋ผ๋ ๋ช ๋ น์ ๋ณด๋ด๋ฉด
2. ํด๋น ์๊ฐ์ ๋ณด๋ธ ํ Callback Queue(Task Queue)์ ๋ณด๋ธ๋ค.
3. ์ดํ Event Loop๋ฅผ ํตํด Call Stack์ผ๋ก ์ด๋ํ๋๋ฐ,
์ด๋, Call Stack์์ ์ด๋ฏธ ์์ ์ค์ธ ๊ฒ์ด ์กด์ฌํ๋ค๋ฉด ์ฒ๋ฆฌ๋ฅผ ๊ธฐ๋ค๋ฆฐ ํ ์ด๋ํ๊ฒ๋๋ค.
๋ฐ๋ผ์ ์ค์ ํ ์๊ฐ + ์ฝ๋ฐฑ ํ์์์ ๋๊ธฐ์๊ฐ์ด ํ์ํ ๊ฒ์ด๋ค.
๋๋ฌธ์ ํญ์ ์ ํํ ์๊ฐ์ ๋ณด์ฅํด์ฃผ์ง ์๋ ๋ฐฉ๋ฒ์ธ ๊ฒ์ด๋ค.
2. Date๋ฅผ ์ด์ฉํ ํ์ด๋จธ
setInterval๊ณผ setTimeout์ delay์ ์ํฅ์ ๋ฐ์ง ์๋ ํ์ด๋จธ๋ฅผ ๋ง๋๋ ๋ฐฉ๋ฒ ์ค ํ๋๋
Date๋ฅผ ์ด์ฉํ๋ ๋ฐฉ๋ฒ์ด๋ค.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date
Date - JavaScript | MDN
JavaScript Date objects represent a single moment in time in a platform-independent format. Date objects encapsulate an integral number that represents milliseconds since the midnight at the beginning of January 1, 1970, UTC (the epoch).
developer.mozilla.org
์๊ฐ์ ์ถ์ถํ ๋ ์ฌ์ฉํ๋ Date ์ค
Date.now()๋ UTC 1970๋
1์ 1์ผ 0์ 0๋ถ 0์ด๋ถํฐ ํจ์๋ฅผ ํธ์ถํ ํ ์์ ๊น์ง ๊ฒฝ๊ณผ๋ ms๋ฅผ ๋ฐํํ๋ ํจ์์ด๋ค.
์ด๋ฅผ ์ด์ฉํ์ฌ ๊ฒฝ๊ณผ ์๊ฐ์ ๊ตฌํ๋ ๋ฐฉ๋ฒ์ ์๋์ ๊ฐ๋ค.
1_ ์์ํ ๋ ํ ๋ฒ ํธ์ถ, ๋๋ ๋ ํ ๋ฒ ํธ์ถ
2_ ๋๋ ์๊ฐ - ์์ ์๊ฐ = ๊ฒฝ๊ณผ์๊ฐ
์ ๋ฐฉ๋ฒ์ ํ์ฉํ์ฌ ํ์ด๋จธ๋ฅผ ๋ง๋ค์ด๋ณผ ์ ์๋ค.
// ์์ ๋ฒํผ -> ์์ ์ํ ์ค์
const [start, setStart] = useState(false);
// ํ์ด๋จธ run ์ํ
const [run, setRun] = useState(false);
// ์์์๊ฐ
let startTimeRef = useRef(null);
// ์๊ฐ state
const [seconds, setSeconds] = useState(0);
const [millseconds10, setMillseconds10] = useState(0);
const [milliseconds1, setMilliseconds1] = useState(0);
useEffect(()=>{
if(start){
timerPlay(); // ์์์๊ฐ ์ ์ฅ ํจ์ ํธ์ถ
setRun(true); // run ์ํ ์ค์
}
else{
clearInterval(intervalRef.current)
setRun(false);
}
},[start])
useEffect(()=>{
if(run){
intervalRef.current = setInterval(() => {
const now = new Date(Date.now() - startTimeRef.current);
if(now.getTime() == stop*1000+1){ //์ค์ ํ ์๊ฐ ์ด๊ณผ์ ๋ฉ์ถค
clearInterval(intervalRef.current)
setRun(false);
}
else{
setSeconds(now.getUTCSeconds()); //์ด
setMillseconds10(now.getUTCMilliseconds().toString()[0]); //๋ฐ๋ฆฌ
setMilliseconds1(now.getUTCMilliseconds().toString()[1]); //๋ฐ๋ฆฌ
}
},10);
}
},[run])
// ์์ ์๊ฐ ์ค์ ํจ์
const timerPlay = ()=>{
if (startTimeRef.current===null){startTimeRef.current = Date.now();}
}
๋๊ธ