리액트 훅에서 setInterval 사용하면 의도대로 동작하지 않는다.
이유는 : https://overreacted.io/making-setinterval-declarative-with-react-hooks/ 여기 참고.
간단하게 정리하면, state가 계속 변하면서 무한 렌더링에 빠지기 때문에. 그래서 커스텀 훅을 만들어서 쓴다.
리렌더링이 되어도 값을 기억할 수 있는 ref 를 활용한다. 이를 활용하지 않으면, 아래처럼 너무 많이 렌더링이 발생했다고 에러를 뿜는다.
위 글을 참고해 useInterval 이라는 훅을 만들었다.
이 함수는 delay 시간동안 callback 함수를 반복해서 실행시킨다. 여기에 추가적으로 shouldContinue 라는 인자를 통해 setInterval이 실행될 필요가 없는 상황에서는 실행되지 않도록 했다. 이를 실행하는 경우가 지정 시간까지 주기적으로 카운트를 해주기 위해서인데, 0에 도달한 경우에는 카운팅이 필요하지 않기 때문에 실행하지 않도록 했다.
chatGPT 님께 이 코드에 대한 리뷰를 부탁드렸는데, 몇 가지 수정 사항을 알려주셨다. 지금 깨달았는데 shoudContinue를 옵셔널로 두면 안되는구나. if문에서 이를 확인하고 있기 때문에, 전달하지 않는 경우 interval 자체가 아예 실행이 안되겠군.
import { useEffect, useRef } from 'react';
// `useInterval` is a custom hook that sets up an interval and returns a cleanup function
// `callback` is the function to be called every `delay` milliseconds
// `delay` is the interval time in milliseconds
// `shouldContinue` is an optional flag that determines whether the interval should be running or not
export const useInterval = (callback: () => void, delay: number, shouldContinue = true) => {
// `savedCallback` is a ref that holds a reference to the `callback` function
// this is necessary because `callback` may change if the component re-renders
const savedCallback = useRef<() => void>();
// this `useEffect` sets the `savedCallback` ref to the passed-in `callback` function
useEffect(() => {
savedCallback.current = callback;
}, [callback]);
// this `useEffect` sets up the interval and returns a cleanup function that clears the interval
useEffect(() => {
if (shouldContinue) {
// `tick` is a function that calls the `savedCallback` function
const tick = () => {
if (savedCallback.current) {
savedCallback.current();
}
};
// `id` is the interval ID
const id = setInterval(tick, delay);
// this cleanup function is called when the component unmounts or when `shouldContinue` changes
return () => clearInterval(id);
}
}, [delay, shouldContinue]);
};
아무튼 이렇게 만든 useInterval 훅은 아래와 같이 활용했다. 아래는 끝나는 시간을 전달하면, 현재로부터 남은 시간을 계산해 state로 리턴해주는 훅이다. 여기서 useInterval로 realTime 을 계속 갱신해주기 때문에, 이를 화면에 렌더링 하면 1초마다 바뀌는 시간이 계속해서 반영된다.
2. DATE 객체끼리 연산하려는데, 타입스크립트 오류 발생함. 일반 자바스크립트에서는 문제가 없는데 이상하다..하면서 아래 링크를 통해 문제를 해결함.
타입스크립트에서는 명시적으로 연산이 가능한 숫자와 연산을 해주어야 한다고 설명하고 있다. 두 date 객체 앞에 + 연산자를 붙여 숫자화 한 뒤 연산해주니 정상 동작한다.
http://ccambo.github.io/Dev/Typescript/1.typescript-problem-solving-and-tips/
'프로젝트 > 데일리 옥션' 카테고리의 다른 글
# 작업일지 9 / Chart.js 적용, 경매가 유효성 검사 (0) | 2023.02.18 |
---|---|
#8 작업일지 / interval함수 리팩토링, 게시글 상세페이지 통신 로직 작성 (0) | 2023.02.15 |
# 작업일지 6 / query parameter 에 접근하기 (0) | 2023.02.10 |
# 작업일지 5 / 알림 페이지와 검색 페이지 구현, 리액트 쿼리 어떻게 써야하징 (0) | 2023.02.09 |
# 작업일지 4 / 모달창 작업, 캐러셀(?) 구현, relative absolute, 유니온타입 활용 (0) | 2023.02.08 |