[React] setTimeOut을 이용한 타이머 설정

뚜벅맨·2021년 8월 16일
6

setTimeOut()

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() 코드는 컴포넌트가 업데이트 될 때 절대 실행되지 않습니다.

clearTimeOut()

setTimeout 타이머를 사용한 경우 타이머를 해제해야 합니다. 위에서 Detail 방문시 2초 후에 UI 사라지게 해주세요~ 라고 코드를 짰습니다. 이 때 2초가 되기도 전에 Detail을 벗어나는 경우, 코드가 길어지거나 꼬이면 남아있는 타이머 때문에 이상한 현상 (a.k.a BUG)이 일어날 수 있습니다. 그래서 컴포넌트가 사라질 때 타이머를 없애는 코드도 추가해주는 것이 좋습니다.

useEffect(()=>{
  let timer = setTimeout(()=>{ alertSet(false) }, 2000);

  return ()=>{ clearTimeout(timer) }
}, []);

useEffect() 안에 return 함수()를 추가하면 컴포넌트가 사라질 때 특정 코드를 실행할 수 있습니다. 여기에 clearTimeout을 추가하면 타이머를 바로 해제할 수 있습니다.

setInterval()

setTimeOut()과 비슷한 함수로 setInterval()이 있습니다. setInterval()은 지정한 밀리초 주기마다 함수를 반복적으로 호출합니다. setTimeout()처럼 setInterval()도 clearTimeout() 메서드를 사용하여 계획된 함수의 실행을 취소할 수 있도록 타이머 ID값을 반환할 수 있습니다.

  useEffect(()=>{
    let timer = setInterval(()=>{ alertSet(false) }, 2000);
  });    

// 2초마다 setInterval()이 계속해서 실행되게 됩니다.

profile
쉽게만 살아가면 재미없어 빙고🐝

0개의 댓글