Function Component에서 Hook을 이용하여 state 관리를 진행합니다. 이 때, setTimeOut을 사용하면 일정 시간 후 코드를 비동기적으로 실행할 수 있습니다.
자바스크립트에서의 문법을 사용합니다.
setTimeout(function() { // Code here }, delay);
위 함수는 보통 두 개의 인자를 설정하여 사용합니다.
1. 호출될 콜백함수
2. 지연시간(delay time)
(Detail.js 파일)
function Detail(){
let [ alert, alertSet ] = useState(true);
useEffect(()=>{
let timer = setTimeout(()=>{ alertSet(false) }, 2000);
});
return (
<Components />
{
alert === true
? (<div className="my-alert2">
<p>재고가 얼마 남지 않았습니다</p>
</div>)
: null
}
)
}
state의 boolean 값에 따라서서 UI가 보였다 안보였다가 하게 되는 코드입니다. 여기에 setTimeOut()을 사용해서 Detail 페이지 방문 후 2초 후에 alert의 state 값이 falsefh 변하면서 alert 박스가 사라지게 설정해 주었습니다.
문제는, Detail 컴포넌트가 업데이트될 때도 useEffect 실행된다는 사실입니다. useEffect()는 컴포넌트가 등장하고 나서 & 업데이트가 되고 나서 항상 실행됩니다.
(Detail.js 파일)
function Detail(){
let [ alert, alertSet ] = useState(true);
let [ inputData, inputDataSet ] = useState('');
useEffect(()=>{
let timer = setTimeout(()=>{ alertSet(false) }, 2000);
});
return (
<Components />
{ inputData }
<input onChange={ (e)=>{ inputDataSet(e.target.value) }}/>
{
alert === true
? (<div className="my-alert2">
<p>재고가 얼마 남지 않았습니다</p>
</div>)
: null
}
)
}
inputData라는 빈 state를 하나 만들고, <input> 태그
를 만들어서 거기 문자가 입력될 때마다 inputData라는 state에 저장되게 해주었습니다. 그리고 inputData를 확인하기 위해서 { inputData }
과 데이터바인딩했습니다.
이제 <input>
에다가 무언가 입력하면 계속 Detail 컴포넌트가 업데이트되고, 따라서 <input>
에 입력할 때마다 useEffect()
도 실행되게 됩니다.
이를 방지하고자 업데이트될 때는 useEffect()
를 실행하지 않도록 하는 코드를 짤 수 있습니다.
useEffect(()=>{
let timer = setTimeout(()=>{ alertSet(false) }, 2000);
}, []);
useEffect() 함수 끝부분에 대괄호[] 를 집어넣을 수 있는데 여기에 state를 넣을 수 있습니다. (대괄호 안에는 여러 개의 state를 넣을 수 있습니다)
useEffect(()=>{
let 타이머 = setTimeout(()=>{ alert변경(false) }, 2000);
}, [ alert ]);
이렇게 대괄호[]를 넣으면 alert라는 이름의 state가 변경이 될 때만 업데이트를 실행해 달라고 전달하는 것이 됩니다. 일종의 실행조건입니다.
이제 setTimeOut은
1. Detail컴포넌트 로드가 될 때
2. alert라는 state가 변경이 될 때에만 실행됩니다.
useEffect(()=>{
let 타이머 = setTimeout(()=>{ alert변경(false) }, 2000);
}, []);
대괄호[]안에 아무 것도 넣지 않은 경우는, 조건을 넣지 않았다고 보아서 이 useEffect() 코드는 컴포넌트가 업데이트 될 때 절대 실행되지 않습니다.
setTimeout 타이머를 사용한 경우 타이머를 해제해야 합니다. 위에서 Detail 방문시 2초 후에 UI 사라지게 해주세요~ 라고 코드를 짰습니다. 이 때 2초가 되기도 전에 Detail을 벗어나는 경우, 코드가 길어지거나 꼬이면 남아있는 타이머 때문에 이상한 현상 (a.k.a BUG)이 일어날 수 있습니다. 그래서 컴포넌트가 사라질 때 타이머를 없애는 코드도 추가해주는 것이 좋습니다.
useEffect(()=>{
let timer = setTimeout(()=>{ alertSet(false) }, 2000);
return ()=>{ clearTimeout(timer) }
}, []);
useEffect() 안에 return 함수()를 추가하면 컴포넌트가 사라질 때 특정 코드를 실행할 수 있습니다. 여기에 clearTimeout을 추가하면 타이머를 바로 해제할 수 있습니다.
setTimeOut()과 비슷한 함수로 setInterval()이 있습니다. setInterval()은 지정한 밀리초 주기마다 함수를 반복적으로 호출합니다. setTimeout()처럼 setInterval()도 clearTimeout() 메서드를 사용하여 계획된 함수의 실행을 취소할 수 있도록 타이머 ID값을 반환할 수 있습니다.
useEffect(()=>{
let timer = setInterval(()=>{ alertSet(false) }, 2000);
});
// 2초마다 setInterval()이 계속해서 실행되게 됩니다.