반응형
로컬 변수를 사용할 때 useRef를 활용할 수 있다.
useRef는 current 속성을 가지고 있고 이 값을 변경해도 컴포넌트가 렌더링되지 않는다.
Timer component에서 시간, 분, 초를 입력받는다고 가정하자.
count할 시간은 시간에 3600, 분에 60을 곱한 후 나온 결과를 초와 함께 더한다.
그리고 setInterval를 담을 interval도 useRef로 선언한다.
const Timer = ({ hh, mm, ss }) => {
const HH = hh ? parseInt(hh) : 0;
const MM = mm ? parseInt(mm) : 0;
const SS = ss ? parseInt(ss) : 0;
const count = useRef(HH * 60 * 60 + MM * 60 + SS);
const interval = useRef(null);
각 시간에 대한 변수는 useState로 선언해둔다.
const [hour, setHour] = useState(intToString(HH));
const [minute, setMinute] = useState(intToString(MM));
const [second, setSecond] = useState(intToString(SS));
padStart 함수를 이용하여 숫자가 10보다 작은 경우는 0을 추가로 붙이도록 한다.
const intToString = (num) => {
return String(num).padStart(2, "0");
};
useEffect로 최초로 렌더링할 때 시간을 계산하여 카운트 다운이 되도록 한다.
count가 HH * 60 * 60 + MM * 60 + SS로 시작하였으므로,
다시 hour, minute, second로 변경한다.
useEffect(() => {
interval.current = setInterval(() => {
count.current -= 1;
setHour(intToString(parseInt(count.current / 3600)));
setMinute(intToString(parseInt((count.current % 3600) / 60)));
setSecond(intToString((count.current % 60)));
}, 1000);
}, []);
매 초가 흐를 때마다 timer를 보여주므로, second가 변경될 때마다 count가 남아있는지 체크한다.
0이 될 경우 clearInterval로 setInterval를 종료한다.
useEffect(() => {
if (count.current <= 0) {
clearInterval(interval.current);
}
}, [second]);
최종코드는 아래와 같다.
import React, { useState, useEffect, useRef } from 'react';
const intToString = (num) => {
return String(num).padStart(2, "0");
};
const Timer = ({ hh, mm, ss }) => {
const HH = hh ? parseInt(hh) : 0;
const MM = mm ? parseInt(mm) : 0;
const SS = ss ? parseInt(ss) : 0;
const count = useRef(HH * 60 * 60 + MM * 60 + SS);
const interval = useRef(null);
const [hour, setHour] = useState(intToString(HH));
const [minute, setMinute] = useState(intToString(MM));
const [second, setSecond] = useState(intToString(SS));
useEffect(() => {
interval.current = setInterval(() => {
count.current -= 1;
setHour(intToString(parseInt(count.current / 3600)));
setMinute(intToString(parseInt((count.current % 3600) / 60)));
setSecond(intToString((count.current % 60)));
}, 1000);
}, []);
useEffect(() => {
if (count.current <= 0) {
clearInterval(interval.current);
}
}, [second]);
return (
<div>
{hour} : {minute} : {second}
</div>
);
};
export default Timer;
아래와 같이 component를 만들어서 사용할 수 있다.
<Timer hh="5" mm="0" ss="9"/>
반응형
'개발 > React' 카테고리의 다른 글
리액트 - 같은 Link를 클릭해도 새로고침 되도록 하기 (리액트 라우터 useLocation) (0) | 2022.03.27 |
---|---|
리액트 - jsconfig.json로 component import 자동완성 (0) | 2022.03.24 |
로그인 폼 만들기 - useReducer로 Input 관리 (0) | 2022.03.20 |
리액트 package.json에서 port 변경 (0) | 2022.03.18 |
로그인 폼 만들기 - Caps Lock 감지 (0) | 2022.03.14 |
댓글