[Typescript] React에서 setInterval 사용하기

박기영·2022년 7월 25일
0

Typescript

목록 보기
3/11

문제 상황

캐러셀 슬라이드를 구현하던 도중, 자동으로 슬라이드가 넘어가게 하기 위해서 setInterval()을 사용하려고 했다.
그런데, 기능 활용법을 알아보던 중 React에서는 setInterval()의 동작이 의도한대로 작동하지 않는다는 글들이 쏟아져 나왔다. 무엇이 문제일까?

이유

보통 주기적으로 상태를 업데이트하기 위해 useEffect와 setInterval을 섞어서 사용하는 경우가 많다.
useEffect는 React Hook으로, props와 state는 언제든 변화할 수 있다. React는 변화된 값을 가지고, 새롭게 렌더링을 하게 된다.
반면, setInterval은 clearInterval를 사용하지않는한 그 값을 변화시킬 수 없다. 즉, 처음 useEffect가 실행되었을 때, 바로 그 값만 참조가 되는 것이다.
따라서, useEffect 내부에서 setInterval을 실행시킨다고 하더라도 이들은 상태 변화를 만들어 낼 수 없는 것이다!

적용

그래서 useInterval이라는 커스텀 Hook이 나왔다.(정식 출시된 기능은 아니라고 한다)
다만, 필자는 Typescript로 프로젝트를 진행 중이었으므로, 타입 선언까지 적용이 된 것을 찾았다.

interface IUseInterval {
  (callback: () => void, interval: number): void;
}

const useInterval: IUseInterval = (callback, interval) => {
  const savedCallback = useRef<(() => void) | null>(null);
  
  useEffect(() => {
    savedCallback.current = callback;
  });

  useEffect(() => {
    function tick() {
      if (savedCallback.current) {
        savedCallback.current();
      }
    }

    let id = setInterval(tick, interval);
    return () => clearInterval(id);
  }, [interval]);
};

useInterval에 props로 들어가는 callback 함수 부분에 setInterval을 적용시키고 싶은 함수를 넣어주면 된다. 아래 처럼!

const [count, setCount] = useState(0);
useInterval(() => setCount(count => count + 1), 1000);

이 예시는, 1초에 한번씩 count의 state가 1씩 증가한다.
setCount 내부에서 사용하는 방법도 잘 살펴봐야한다. 저기까지가 반드시 지켜줘야할 부분이다.
저 방식으로 setState를 진행해야지 업데이트 된 값들을 사용할 수 있게된다.

참고 자료

참고 자료1
참고 자료2
참고 자료3

profile
나를 믿는 사람들을, 실망시키지 않도록

0개의 댓글