React Query 폴링: 작업이 끝나면 refetchInterval 멈추기
React Query의 refetchInterval로 영상 Job을 폴링하세요. 백엔드를 호출하고, API가 제안하는 간격만큼 기다리다가, Job이 종료되면 false를 반환하면 됩니다.

React Query(TanStack Query)로 폴링하려면 useQuery에 refetchInterval을 설정하세요. 값은 밀리초 단위 숫자, 쿼리를 받아 다음 대기 시간을 반환하는 함수, 또는 폴링을 멈추는 false입니다. AI 영상 Job이라면 Job이 종료 상태가 되는 즉시 false를 반환하고 그 전에는 API가 제안하는 간격만큼 기다리며, queryFn은 영상 API가 아니라 여러분의 백엔드를 가리키게 하세요. API 키는 서버에 있어야 하기 때문입니다.
TanStack 관련 내용은 폴링 가이드, UseQueryOptions 레퍼런스, 중요한 기본값 문서에서, Sume 관련 내용은 Job과 결과 (영문), 인증, Sume API 레퍼런스에서 가져왔습니다. 모두 2026-09-27에 확인했습니다. Sume에는 React 패키지가 없습니다. 브라우저는 여러분의 백엔드를 호출하고, 백엔드가 HTTPS로 Sume를 호출합니다.
영상 API 대신 왜 내 백엔드를 폴링하나요?
키를 브라우저로 보낼 수 없기 때문입니다. Sume 문서는 브라우저와 모바일 클라이언트가 API 키를 붙여 주는 백엔드를 호출해야 하며, 키는 프론트엔드 JavaScript나 모바일 앱에 절대 두면 안 된다고 안내합니다. 그렇게 하지 않으면 어떻게 되는지는 브라우저에서 Sume API 호출 시 CORS 오류에서 다룹니다. 여러분의 상태 라우트는 요청을 검증하고 로그인한 사용자가 그 Job의 소유자인지 확인한 뒤, 키로 GET /v1/jobs/{id}/status를 읽고 페이로드의 data 객체를 반환합니다. POST /v1/videos로 시작한 Job도 여기서 읽을 수 있습니다.
Job이 끝나면 폴링을 어떻게 멈추나요?
간격 함수가 묻는 두 가지 질문에 상태 페이로드가 모두 답합니다. terminal은 멈출지 여부를, next_poll_after_seconds는 얼마나 기다릴지를 알려 줍니다. 페이로드의 나머지는 영상 생성 Job 상태 API 폴링하기에서 다룹니다. TanStack의 폴링 가이드도 작업을 폴링할 때 같은 형태를 씁니다. false를 반환하면 간격 타이머가 해제되고, 나중에 함수가 다시 숫자를 반환하면 폴링이 저절로 재개됩니다.
| 옵션 또는 필드 | 출처 | 역할 |
|---|---|---|
refetchInterval | TanStack Query | 밀리초 또는 쿼리를 받는 함수. false면 폴링 중지. 기본값 false |
refetchIntervalInBackground | TanStack Query | 기본값 false. 탭이 백그라운드에 있는 동안 폴링 일시 중지 |
retry | TanStack Query | 실패한 쿼리는 기본적으로 클라이언트에서 지수 백오프로 3회 재시도 |
terminal | Sume Job 상태 | Job이 완료, 실패, 취소 중 하나로 끝나 폴링을 멈춰도 될 때 true |
next_poll_after_seconds | Sume Job 상태 | 다음 폴링 전 권장 최소 대기 시간. 종료 후에는 null |
result_ready | Sume Job 상태 | /result가 결과를 반환할 수 있을 때만 true |
import { useQuery } from "@tanstack/react-query";
type JobStatus = {
sume_status: "queued" | "processing" | "completed" | "failed" | "canceled";
terminal: boolean;
result_ready: boolean;
next_poll_after_seconds: number | null;
};
export function useVideoJob(jobId: string) {
return useQuery({
queryKey: ["video-job", jobId],
queryFn: async (): Promise<JobStatus> => {
const res = await fetch(`/api/video-jobs/${jobId}`); // your backend
if (!res.ok) throw new Error(`status read failed: ${res.status}`);
return res.json();
},
refetchInterval: (query) => {
const job = query.state.data;
if (job?.terminal) return false; // completed, failed or canceled
return (job?.next_poll_after_seconds ?? 5) * 1000;
},
});
}Job이 끝나면 컴포넌트는 무엇을 해야 하나요?
terminal이 true가 되면 sume_status에 따라 분기하세요.
completed:result_ready가 true가 되면 백엔드가GET /v1/jobs/{id}/result를 읽어 컴포넌트에 미디어 URL을 넘기게 하세요.failed또는canceled: 결과 라우트는 이런 Job에409 job_not_completed로 응답하므로, 백엔드는 대신GET /v1/jobs/{id}에서 오류를 읽습니다.- 두 경우 모두 간격 함수가 이미
false를 반환했으므로 폴링 요청이 더 나가지 않습니다.
탭이 숨겨지거나 폴링이 실패하면 어떻게 되나요?
refetchIntervalInBackground: true를 설정하지 않으면 탭이 백그라운드에 있는 동안 폴링이 일시 중지됩니다. Job은 멈추지 않습니다. 클라이언트가 지켜보기를 멈춰도 Job은 취소되지 않고 계속 실행되며 계속 과금됩니다. 다음 폴링이 이어서 Job 상태를 가져옵니다.
실패한 queryFn은 쿼리가 오류를 보고하기 전에 재시도되며, 상태 읽기에서 받은 429나 5xx는 작업이 아니라 읽기가 실패했다는 뜻입니다. 모든 탭은 여러분 서버의 키를 거쳐 폴링하며, 읽기에는 키마다 별도의 분당 예산이 있고 그 크기는 쓰기 예산의 마흔 배입니다. next_poll_after_seconds를 따르고 숨겨진 탭의 폴링을 멈추면 그 트래픽이 줄어듭니다.
대신 롱 폴링, SSE, WebSocket을 쓸 수 있나요?
Sume API에서는 쓸 수 없습니다. 현재 Developer API에는 SSE나 WebSocket 전송이 없으며, GET /v1/jobs/:id/events는 스트림이 아니라 pull 스냅샷입니다. 가장 가까운 것은 제출할 때 쓰는 sync 모드나 그 별칭인 subscribe로, 최대 30초 동안 한 번 기다리는 방식인데 영상 Job은 대개 그보다 오래 걸립니다. 푸시가 필요하면 Job과 함께 webhook_url(POST /v1/videos에서는 callback_url)을 보내 Job이 끝날 때 Sume가 서버에 알리게 하고, 서버는 앱이 이미 쓰는 방식으로 브라우저에 알리게 하세요. 그동안 무엇을 보여 줄지는 AI 영상 생성 API 진행 상황 업데이트에서 다룹니다.
출처
관련 글
연동 카테고리의 다른 글
- Roo Code MCP 서버: streamable-http로 Sume 추가
Roo Code에 원격 MCP 서버를 추가하세요. Sume 호스팅 MCP용 streamable-http 항목과 API 키 헤더를 넣고, 유료 도구는 alwaysAllow에서 빼 두세요.
- EventBridge로 Lambda 함수를 스케줄에 따라 실행하는 방법
EventBridge Scheduler로 cron 또는 rate 스케줄에 따라 Lambda 함수를 호출하세요. 매일 만드는 AI 영상이라면 예약 시각으로 만든 키로 실행을 시작하고 바로 반환하세요.
- Shopify 제품 영상 AI API: products/create 웹훅
Shopify products/create 웹훅에 오 초 안에 응답하고, 큐에서 Sume Format을 실행한 뒤 staged upload로 MP4를 Shopify에 올리세요.
- Slack 영상 생성 봇: Sume API로 만드는 슬래시 커맨드
Slack 슬래시 커맨드에 3000 ms 안에 응답하고 callback_url과 함께 POST /v1/videos를 제출한 뒤, Sume 웹훅이 오면 response_url로 URL을 게시하세요.
작성자 Sume