훅(Hook)

[useTimeout] 일정 시간 뒤 딱 한 번, 그 전엔 취소되는 타이머 훅

setTimeout을 컴포넌트 상태에 맞춰 안전하게 쓰는 훅. "삭제 되돌리기"처럼 예약했다가 되돌리는 흐름을 몇 줄로 만듭니다.

ReactTypeScriptuseRefsetTimeoutCustom Hook
라이브 데모
새 탭에서 열기
데모 불러오는 중…

제작 과정

한 줄 요약 일정 시간이 지나면 함수를 딱 한 번 실행하고, 그 전에 마음이 바뀌면 깔끔하게 취소할 수 있는 타이머 훅이에요.

이럴 때 필요해요

브라우저의 setTimeout을 리액트 컴포넌트 안에서 그냥 쓰면 두 가지가 자꾸 발목을 잡아요. 하나는 컴포넌트가 화면에서 사라져도 타이머가 살아남아 에러를 내는 것(정리 안 됨), 다른 하나는 타이머가 "예약된 순간의 옛날 값"을 들고 실행돼서 최신 상태를 못 보는 것(이걸 스테일 클로저(stale closure) 함수가 만들어질 때의 낡은 값에 갇히는 현상이라고 불러요).

useTimeout은 이 두 가지를 대신 처리해 줍니다. "삭제하고 4초 안에 되돌리기", "토스트 알림 자동 닫기", "잠깐 보여줬다 사라지는 안내"처럼 한 번만 실행되는 지연 동작이 필요할 때 쓰면 됩니다.

어떻게 동작하나

  1. delay(밀리초)를 숫자로 넘기면 그 시간 뒤에 콜백이 한 번 실행되도록 예약돼요.

  2. 실행할 함수는 매번 최신 버전을 ref라는 보관함에 넣어 둬서, 타이머가 터지는 순간에도 항상 "지금 상태"를 기준으로 동작해요 (옛날 값에 갇히지 않음).

  3. delaynull로 바꾸면 예약이 즉시 취소돼요. 그래서 "되돌리기"를 누르면 상태가 바뀌면서 delaynull이 되고, 타이머가 자동으로 사라집니다.

  4. 컴포넌트가 화면에서 사라질 때도 예약된 타이머를 알아서 정리해 줘요.

핵심은 이거예요

타이머를 직접 켜고 끄지 마세요 delay에 "지금 예약이 필요한지"만 알려주면(있으면 숫자 / 없으면 null) 켜고 끄는 건 훅이 알아서 합니다. 이 한 가지만 이해하면 나머지는 따라와요.

놓치기 쉬운 것

  • setTimeout을 컴포넌트에서 직접 쓰면 정리(cleanup)를 깜빡하기 쉬운데, 그러면 사라진 화면을 건드리려다 경고가 떠요. 이 훅은 그 정리를 자동으로 해 줍니다.

  • "되돌리기"는 별도 취소 코드가 아니라 그냥 delaynull로 바꾸는 것이에요. 명령형(타이머 ID를 들고 clearTimeout)으로 생각하면 더 복잡해집니다.

  • 진행 바의 카운트다운은 타이머와 별개인 CSS 애니메이션이에요. 실제 "언제 실행되느냐"는 delay 숫자가 결정합니다.

이런 곳에 써요

  • 메일파일 삭제 후 몇 초간 뜨는 "되돌리기" 배너 (Gmail 보관취소처럼)

  • 토스트스낵바 자동 닫힘, 잠깐 떴다 사라지는 복사 완료 안내

  • 일정 시간 입력이 없으면 자동 저장하거나 세션 안내를 띄우는 동작

소스 코드

· 데모 페이지에서 자동 추출
import type { Metadata } from "next";
import { TimeoutDemo } from "./-components/TimeoutDemo";

export const metadata: Metadata = {
  title: "useTimeout (데모)",
  description:
    "선언적 setTimeout 훅. delay가 지나면 한 번 실행, null이면 취소. '삭제 되돌리기' 패턴으로 예약과 취소 흐름을 보여줍니다.",
  robots: { index: false, follow: false },
};

export default function Page() {
  return (
    <main className="flex min-h-[100dvh] items-center justify-center bg-gradient-to-br from-violet-50 via-white to-fuchsia-50/60">
      <TimeoutDemo />
    </main>
  );
}
21조회수

댓글