data-fetching

star 11

TanStack Query 기반 데이터 페칭 패턴

BangDori By BangDori schedule Updated 3/2/2026

name: data-fetching description: TanStack Query 기반 데이터 페칭 패턴 user-invocable: false

Data Fetching Patterns

TanStack Query (@tanstack/react-query)를 사용한 데이터 페칭 규칙.

구조

src/renderer/
├── queries/
│   ├── client.ts    # QueryClient 인스턴스 (staleTime: 30s)
│   └── keys.ts      # 쿼리 키 팩토리
└── hooks/
    ├── useLaunchdJobs.ts   # useQuery 예시
    ├── useJobActions.ts    # useMutation 예시
    ├── useSettings.ts      # 공유 상태 예시
    ├── useFocusMode.ts     # optimistic update 예시
    └── useCalendarData.ts  # 복합 훅 예시

쿼리 키

src/renderer/queries/keys.ts에 정의된 팩토리 사용:

queryKeys.jobs.list()        // ["jobs", "list"]
queryKeys.calendar.events()  // ["calendar", "events"]
queryKeys.settings.get()     // ["settings", "get"]

새 쿼리 추가 시 반드시 keys.ts에 키 정의.

읽기 (useQuery)

const { data: jobs = [], isLoading, error } = useQuery({
  queryKey: queryKeys.jobs.list(),
  queryFn: () => window.electronAPI.listJobs(),
  refetchInterval: JOB_POLLING_INTERVAL_MS,  // 폴링 (선택)
});

조건부 폴링

running job이 있을 때만 빠르게 폴링:

refetchInterval: (query) =>
  (query.state.data?.length ?? 0) > 0 ? 1000 : false,

쓰기 (useMutation)

const mutation = useMutation({
  mutationFn: (settings: AppSettings) =>
    window.electronAPI.setSettings(settings),
  onSuccess: () => {
    queryClient.invalidateQueries({ queryKey: queryKeys.settings.all });
  },
});

낙관적 업데이트

const mutation = useMutation({
  mutationFn: (event: LocalEvent) => window.electronAPI.addLocalEvent(event),
  onMutate: async (event) => {
    await queryClient.cancelQueries({ queryKey: queryKeys.calendar.events() });
    const previous = queryClient.getQueryData(queryKeys.calendar.events());
    queryClient.setQueryData(queryKeys.calendar.events(), (old = []) =>
      [...old, toCalendarEvent(event)],
    );
    return { previous };
  },
  onError: (_err, _vars, context) => {
    if (context?.previous)
      queryClient.setQueryData(queryKeys.calendar.events(), context.previous);
  },
  onSettled: () => {
    queryClient.invalidateQueries({ queryKey: queryKeys.calendar.events() });
  },
});

핵심 규칙

  1. 컴포넌트에서 window.electronAPI 직접 호출 금지 — 반드시 hooks 사용
  2. mutation 성공 시 관련 쿼리 invalidateQueries 필수
  3. 낙관적 업데이트는 onMutate + onError + onSettled 세트
  4. 새 도메인 추가 시 queries/keys.ts에 키 팩토리 추가
  5. window.electronAPI.onWindowShow 이벤트 시 invalidateQueries로 새로고침
Install via CLI
npx skills add https://github.com/BangDori/prowl --skill data-fetching
Repository Details
star Stars 11
call_split Forks 0
navigation Branch main
article Path SKILL.md
More from Creator