Skip to content

fetching, caching, synchronizing and updating server state in your web applications (version 5, WIP) ๐Ÿ“ก

Notifications You must be signed in to change notification settings

8dong/react-query

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

12 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

@tanstack/react-query (v5.51.1)

react-query๋Š” react application์—์„œ ์„œ๋ฒ„ ์ƒํƒœ ํŽ˜์นญ, ์บ์‹ฑ, ๋™๊ธฐํ™” ๋ฐ ์—…๋ฐ์ดํŠธ๋ฅผ ๋ณด๋‹ค ์‰ฝ๊ฒŒ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ฃผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ž…๋‹ˆ๋‹ค.

QueryClient & QueryClientProvider

QueryClient๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋‚ด ์œ ์ผํ•ด์•ผํ•˜๋ฉฐ QueryClient๋ฅผ ํ†ตํ•ด ์บ์‹œ์™€ ์ƒํ˜ธ์ž‘์šฉ์„ ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ๋ชจ๋“  query์™€ mutation์— ๊ธฐ๋ณธ ์˜ต์…˜์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

QueryClient๋Š” ์ƒ์„ฑ์ž๋กœ new ์—ฐ์‚ฐ์ž์™€ ํ•จ๊ป˜ ํ˜ธ์ถœํ•ด์•ผ ํ•˜๋ฉฐ, ํ˜ธ์ถœํ•  ๋•Œ defaultOptions ํ”„๋กœํผํ‹ฐ์— ์ฟผ๋ฆฌ์— ๋Œ€ํ•œ ์˜ต์…˜์„ ์„ค์ •ํ•œ ๊ฐ์ฒด๋ฅผ ์ธ์ˆ˜๋กœ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

QueryClientProvider ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ตœ์ƒ๋‹จ์— ์œ„์น˜์‹œํ‚ค๊ณ  client props์— ์ƒ์„ฑํ•œ QueryClient ์ธ์Šคํ„ด์Šค๋ฅผ ์ „๋‹ฌํ•ด์ค๋‹ˆ๋‹ค.

import { QueryClient, QueryClientProvider } from '@tanstack/react-query';

export default function App() {
  const queryClient = new QueryClient({
    defaultOptions: {
      // ๋ชจ๋“  ์ฟผ๋ฆฌ์— ๊ณตํ†ต์ ์œผ๋กœ ์ ์šฉ๋˜๋Š” ์˜ต์…˜์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
      queries: {
        // ์ฟผ๋ฆฌ๋ฅผ ์ฒ˜์Œ ์‹คํ–‰ํ•  ๋•Œ ์‚ฌ์šฉ๋˜๋Š” ์ดˆ๊ธฐ ๋ฐ์ดํ„ฐ์ž…๋‹ˆ๋‹ค.
        initialData: undefined,

        // ์ฟผ๋ฆฌ๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ํŽ˜์นญํ•˜๋Š” ๋™์•ˆ ์ปดํฌ๋„ŒํŠธ์— ์ œ๊ณต๋  ์ž„์‹œ ๋ฐ์ดํ„ฐ๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
        placeholderData: undefined,

        // ์ดˆ๊ธฐ ๋ฐ์ดํ„ฐ๊ฐ€ ๋งˆ์ง€๋ง‰์œผ๋กœ ์—…๋ฐ์ดํŠธ๋œ ์‹œ๊ฐ„์„ ํƒ€์ž„์Šคํƒฌํ”„(๋ฐ€๋ฆฌ์ดˆ)๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
        initialDataUpdatedAt: undefined,

        // ์ฟผ๋ฆฌ์™€ ๊ด€๋ จ๋œ ์ถ”๊ฐ€ ์ •๋ณด๋ฅผ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
        // meta๋Š” ์ฟผ๋ฆฌ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๋ชจ๋“  ๊ณณ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
        meta: undefined,

        // ์ฟผ๋ฆฌ์˜ ์š”์ฒญ ๋ฐฉ์‹์„ ์„ค์ •ํ•˜๋Š” ์˜ต์…˜์ž…๋‹ˆ๋‹ค.
        // online: ์š”์ฒญ์„ ์šฐ์„ ์ ์œผ๋กœ ์ˆ˜ํ–‰ํ•˜๊ณ  ์บ์‹œ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ํ•„์š”์‹œ์— ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
        // offlineFirst: ์บ์‹œ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์šฐ์„ ์ ์œผ๋กœ ์‚ฌ์šฉํ•˜์—ฌ ์š”์ฒญ ์ˆ˜ํ–‰์„ ์ตœ์†Œํ™”ํ•ฉ๋‹ˆ๋‹ค.
        // always: ์บ์‹œ๋œ ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ๋”๋ผ๋„ ํ•ญ์ƒ ์š”์ฒญ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.
        networkMode: 'online',

        // ์ปดํฌ๋„ŒํŠธ์˜ ๋ฆฌ๋ Œ๋”๋ง์„ ์ œ์–ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
        notifyOnChangeProps: 'all',

        // ์ฟผ๋ฆฌ ํ™œ์„ฑํ™” ์—ฌ๋ถ€๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
        enabled: true,

        // ์ฟผ๋ฆฌ ๋ฐ์ดํ„ฐ๊ฐ€ fresh ์ƒํƒœ์—์„œ stale ์ƒํƒœ๋กœ ๋ณ€๊ฒฝ๋˜๊ธฐ๊นŒ์ง€์˜ ์‹œ๊ฐ„์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
        staleTime: 0,

        // inactive ์ƒํƒœ์ธ ์ฟผ๋ฆฌ ๋ฐ์ดํ„ฐ๊ฐ€ ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํŒ…๋˜๊ธฐ๊นŒ์ง€์˜ ์‹œ๊ฐ„์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
        gcTime: 30000,

        // ์ฟผ๋ฆฌ ์‹คํŒจ์‹œ ์žฌ์‹œ๋„ ํšŸ์ˆ˜๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
        retry: 3,

        // retry ์‚ฌ์ด์˜ ๋Œ€๊ธฐ ์‹œ๊ฐ„์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
        // ์ฒซ ๋ฒˆ์งธ ์ธ์ˆ˜๋กœ๋Š” ์‹คํŒจ ํšŸ์ˆ˜, ๋‘ ๋ฒˆ์žฌ ์ธ์ˆ˜๋กœ๋Š” ์—๋Ÿฌ ๊ฐ์ฒด๋ฅผ ์ „๋‹ฌ๋ฐ›์Šต๋‹ˆ๋‹ค.
        retryDelay: (failureCount, error) => Math.min(1000 * 2 ** failureCount, 30000),

        // ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋งˆ์šดํŠธ๋  ๋•Œ ์‹คํŒจํ•œ ์ฟผ๋ฆฌ๋ฅผ ๋‹ค์‹œ ์‹œ๋„ํ• ์ง€ ์—ฌ๋ถ€๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
        retryOnMount: true,

        // ์ฟผ๋ฆฌ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ผ์ •ํ•œ ๊ฐ„๊ฒฉ์œผ๋กœ refetchingํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
        refetchInterval: false,

        // ์ฟผ๋ฆฌ๊ฐ€ ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์ƒํ…Œ์—์„œ๋„ ์ผ์ •ํ•œ ๊ฐ„๊ฒฉ์œผ๋กœ refetchingํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
        refetchIntervalInBackground: false,

        // ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋งˆ์šดํŠธ๋  ๋•Œ ์ฟผ๋ฆฌ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ž๋™์œผ๋กœ fetchingํ•  ์ง€ ์—ฌ๋ถ€๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
        refetchOnMount: true,

        // ๋„คํŠธ์›Œํฌ๊ฐ€ ๋‹ค์‹œ ์—ฐ๊ฒฐ๋  ๋•Œ ์ฟผ๋ฆฌ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ž๋™์œผ๋กœ fetchingํ•  ์ง€ ์—ฌ๋ถ€๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
        refetchOnReconnect: true,

        // ๋ธŒ๋ผ์šฐ์ €์— ๋‹ค์‹œ ํฌ์ปค์‹ฑ๋˜์—ˆ์„ ๋•Œ ์ฟผ๋ฆฌ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ž๋™์œผ๋กœ fetchingํ•  ์ง€ ์—ฌ๋ถ€๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
        refetchOnWindowFocus: true,

        // ์ฟผ๋ฆฌ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€๊ณตํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ์˜ต์…˜์œผ๋กœ ์ฟผ๋ฆฌ ์›๋ณธ ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ •ํ•˜๊ฑฐ๋‚˜ ํ•„ํ„ฐ๋งํ•  ๋•Œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
        // ์ธ์ˆ˜๋กœ ์›๋ณธ ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌ๋ฐ›์œผ๋ฉฐ ๋ฐ˜ํ™˜๊ฐ’์ด ์ตœ์ข…์ ์œผ๋กœ ๋ฐ˜ํ™˜๋˜๋Š” data์— ๋ฐ”์ธ๋”ฉ๋ฉ๋‹ˆ๋‹ค.
        select: undefined,

        // ๊ธฐ์กด ๋ฐ์ดํ„ฐ์™€ ์ƒˆ๋กœ์šด ๋ฐ์ดํ„ฐ ๊ฐ„์˜ ์ฐจ์ด์ ์„ ํšจ์œจ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋˜๋Š” ์˜ต์…˜์ž…๋‹ˆ๋‹ค.
        // true: ๋ณ€๊ฒฝ๋œ ๋ถ€๋ถ„๋งŒ ์—…๋ฐ์ดํŠธํ•˜๊ณ  ๋‚˜๋จธ์ง€ ๋ฐ์ดํ„ฐ๋Š” ์žฌ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
        // false: ๋ฐ์ดํ„ฐ๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค ์ „์ฒด ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋ฅผ ์ƒˆ๋กœ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
        structuralSharing: true,

        // ์ฟผ๋ฆฌ์—์„œ ๋ฐœ์ƒํ•œ ์—๋Ÿฌ๋ฅผ ์ปดํฌ๋„ŒํŠธ ๋˜๋Š” ์ƒ์œ„ ์ปจํ…์ŠคํŠธ์—๊ฒŒ ์ „๋‹ฌ๋˜๋„๋ก ์„ค์ •ํ•˜๋Š” ์˜ต์…ฅ์ž…๋‹ˆ๋‹ค.
        throwOnError: false,

        // ์ฟผ๋ฆฌ์˜ ๊ธฐ๋ณธ ๋™์ž‘ ๋ฐฉ์‹์„ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋Š” ์˜ต์…˜์ž…๋‹ˆ๋‹ค.
        behavior: {
          // queryFn์ด ์‹คํ–‰๋˜๊ธฐ ์ „์— ์‹คํ–‰๋˜๋Š” ๋ฉ”์„œ๋“œ์ž…๋‹ˆ๋‹ค.
          onFetch(context) {
            // useQuery์— ์ง€์ •ํ•œ queryFn๊ณผ ๋™์ผํ•œ ํ•จ์ˆ˜์ด๋ฉฐ ์ฟผ๋ฆฌ ํ•จ์ˆ˜์— ์ง์ ‘ ์ ‘๊ทผํ•˜๊ณ  ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
            context.fetchFn();

            // refetch ์š”์ฒญ์„ ์ทจ์†Œํ•  ์ˆ˜ ์žˆ๋Š” ์˜ต์…˜์ด๋ฉฐ false๋กœ ์„ค์ •์‹œ refetch๋ฅผ ๋ง‰์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
            context.fetchOptions?.cancelRefetch;
            // ์ฟผ๋ฆฌ๊ฐ€ ์ดˆ๊ธฐ ์ƒํƒœ์ผ ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ํ”„๋กœ๋ฏธ์Šค ๊ฐ์ฒด๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
            context.fetchOptions?.initialPromise;
            // ํŽ˜์ด์ง€๋„ค์ด์…˜์ด๋‚˜ ๋ฌดํ•œ ์Šคํฌ๋กค ์‹œ ๋” ๋งŽ์€ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ฌ ๋•Œ ๋ฐฉํ–ฅ('forward', 'backward')์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
            context.fetchOptions?.meta?.fetchMore?.direction;

            // ์ฟผ๋ฆฌ๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ์‚ฌ์šฉ๋œ ์˜ต์…˜๋“ค์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
            context.options;

            // useQuery์—์„œ ์ง€์ •ํ•œ queryKey ๊ฐ’์„ ๊ฐ–๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
            context.queryKey;

            // AbortSignal๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ fetch ์š”์ฒญ์„ ์ทจ์†Œํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ฃผ๋Š” AbortSignal ๊ฐ์ฒด๊ฐ€ ๋ฐ”์ธ๋”ฉ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.
            context.signal;

            // ์ฟผ๋ฆฌ์˜ ํ˜„์žฌ ์ƒํƒœ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
            context.state;
          }
        }
      },
      // ๋ชจ๋“  ๋ฎคํ…Œ์ด์…˜์— ๊ณตํ†ต์ ์œผ๋กœ ์ ์šฉ๋˜๋Š” ์˜ต์…˜์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
      mutations: {
        scope: {
          // ๋ณ‘๋ ฌ๋กœ ์‹คํ–‰๋˜๋Š” ์—ฌ๋Ÿฌ mutationFn ํ•จ์ˆ˜์ค‘ id๋กœ ์ž‘์„ฑ๋œ mutaitonFn๋“ค์€ ์ง๋ ฌ๋กœ ์‹คํ–‰๋˜๋„๋ก ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
          id: ''
        },

        // mutationFn ์„ฑ๊ณต์‹œ ์‹คํ–‰๋˜๋Š” ๋ฉ”์„œ๋“œ์ž…๋‹ˆ๋‹ค.
        onSuccess: undefined,

        // mutationFn ์‹คํŒจ์‹œ ์‹คํ–‰๋˜๋Š” ๋ฉ”์„œ๋“œ์ž…๋‹ˆ๋‹ค.
        onError: undefined,

        // mutationFn ์„ฑ๊ณต ํ˜น์€ ์‹คํŒจ์‹œ ์‹คํ–‰๋˜๋Š” ๋ฉ”์„œ๋“œ์ž…๋‹ˆ๋‹ค.
        onSettled: undefined
      },
      // SSR์ด๋‚˜ SSG ํ™˜๊ฒฝ์—์„œ dehydrate์‹œ ์ฟผ๋ฆฌ ์ƒํƒœ ์ฒ˜๋ฆฌ๋ฅผ ์ œ์–ดํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
      dehydrate: {
        // ๋ฐ์ดํ„ฐ์˜ ์ง๋ ฌํ™” ๋ฐฉ์‹์„ ์ •์˜ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.
        serializeData: undefined,

        // ํŠน์ • ์ฟผ๋ฆฌ๋ฅผ ์ง๋ ฌํ™”ํ• ์ง€ ์—ฌ๋ถ€๋ฅผ ๊ฒฐ์ •ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.
        shouldDehydrateQuery: () => true,

        // ํŠน์ • ๋ฎคํ…Œ์ด์…˜์„ ์ง๋ ฌํ™”ํ• ์ง€ ์—ฌ๋ถ€๋ฅผ ๊ฒฐ์ •ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.
        shouldDehydrateMutation: () => false
      },
      // SSR์ด๋‚˜ SSG ํ™˜๊ฒฝ์—์„œ hydrate์‹œ ์ฟผ๋ฆฌ ์ƒํƒœ ์ฒ˜๋ฆฌ๋ฅผ ์ œ์–ดํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
      hydrate: {
        // ๋ฐ์ดํ„ฐ์˜ ์—ญ์ง๋ ฌํ™” ๋ฐฉ์‹์„ ์ •์˜ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.
        deserializeData: undefined,

        // MutationOptions์„ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.
        mutations: {
          // ...MutationOptions
        },

        // QueryOptions์„ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.
        queries: {
          // ...QueryOptions
        }
      }
    }
  });

  // QueryClientProvider๋ฅผ ์ตœ์ƒ๋‹จ์—์„œ ๊ฐ์‹ธ์ฃผ๊ณ  QueryClient ์ธ์Šคํ„ด์Šค๋ฅผ client props๋กœ ๋„ฃ์–ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์—ฐ๊ฒฐํ•ด์•ผ ํ•œ๋‹ค.
  return <QueryClientProvider client={queryClient}>,,,</QueryClientProvider>;
}

Using App Router

QueryCLientProvider Component

QueryClientProvider ์ปดํฌ๋„ŒํŠธ๋Š” Context API๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์— ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์œผ๋ฏ€๋กœ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๋กœ ๋ถ„๋ฆฌํ•˜์—ฌ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

// ReactQueryProviders.tsx
'use client';

import { useState, PropsWithChildren } from 'react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';

export default function ReactQueryProviders({ children }: PropsWithChildren) {
  const [queryClient] = useState(
    () =>
      new QueryClient({
        defaultOptions: {
          queries: {
            // ํด๋ผ์ด์–ธํŠธ์ธก์—์„œ ์ฆ‰์‹œ refetching๋˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด์„œ staleTime ๊ฐ’์„ 0์œผ๋กœ ์‚ฌ์šฉ๋˜์ฆŒ ๊ฒƒ์„ ๋ฐฉ์ง€
            staleTime: 60 * 1000
          }
        }
      })
  );

  return (
    <QueryClientProvider client={queryClient}>
      {children}
    </QueryClientProvider>>
  )
}
// app/layout.tsx
import { PropsWithChildren } from 'react';

import ReactQueryProviders from '@/shared/components/ReactQueryProviders';

export default function RootLayout({ children }: PropsWithChildren) {
  return (
    <html>
      <head />
      <body>
        <ReactQueryProviders>{children}</ReactQueryProviders>
      </body>
    </html>
  );
}

prefetching & de/hydrate

์„œ๋ฒ„์—์„œ prefethํ•œ ์ฟผ๋ฆฌ๋“ค์„ ๊ฐ–๋Š” queryClient๋ฅผ dehydrate์‹œ์ผฐ๋‹ค๊ฐ€ ์ดํ›„ ํด๋ผ์ด์–ธํŠธ์ธก์— ์ „๋‹ฌํ•  ๋•Œ๋Š” hydrate ์‹œ์ผœ ์ „๋‹ฌํ•ด์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

// getDehydratedQuery.ts

import {
  QueryClient,
  dehydrate,
  QueryState,
  QueryKey
} from '@tanstack/react-query';
import { cache } from 'react';

import { isEqual } from '@/utils';

// cache ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ QueryClient๋ฅผ ๋งค๋ฒˆ ์ƒ์„ฑํ•˜์ง€ ์•Š๊ณ  ์บ์‹ฑ๋œ queryClient๋ฅผ ์žฌ์‚ฌ์šฉ
export const getQueryClient = cache(() => new QueryClient());

type UnwrapPromise<T> = T extends Promise<infer U> ? U : T;

interface QueryProps<ResponseType = unknown> {
  queryKey: QueryKey;
  queryFn: () => Promise<ResponseType>;
}

interface DehydratedQueryExtended<TData = unknown, TError = unknown> {
  state: QueryState<TData, TError>;
}

export async function getDehydratedQuery<Q extends QueryProps>({
  queryKey,
  queryFn,
}: Q) {
  const queryClient = getQueryClient();

  // ํ•„์š”ํ•œ ์ฟผ๋ฆฌ๋ฅผ prefetching
  await queryClient.prefetchQuery({ queryKey, queryFn });

  // perfetchingํ•œ ์ฟผ๋ฆฌ๋ฅผ ๊ฐ–๊ณ  ์žˆ๋Š” queryClient๋ฅผ dehydate
  // dehydate ๋ฉ”์„œ๋“œ๋Š” ์ฟผ๋ฆฌ๋“ค์„ ์ง๋ ฌํ™”์‹œํ‚ค๊ณ  ์ด๋ฅผ ์ด์šฉํ•˜์—ฌ per-rendering
  const { queries } = dehydrate(queryClient);

  // dehydate ํ•จ์ˆ˜๋Š” prefetcingํ•œ ๋ชจ๋“  ๋ฐ์ดํ„ฐ๋“ค์„ ๋ฐ˜ํ™˜ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์š”์ฒญํ•œ ์ฟผ๋ฆฌ๋งŒ์„ ํ•„ํ„ฐ๋งํ•˜์—ฌ ๋ฐ˜ํ™˜
  const [dehydratedQuery] = queries.filter((query) =>
    isEqual(query.queryKey, queryKey)
  );

  return dehydratedQuery as DehydratedQueryExtended<
    UnwrapPromise<ReturnType<Q['queryFn']>>
  >;
}
// app/page.tsx

import { HydrationBoundary } from 'react-query';

import { getDehydratedQuery } from '@/app/shared/utils/getDehydratedQuery';

export default async function Home({ children }: PropsWithChildren) {
  const { queryKey, queryFn } = queryOptions.all();

  const query = await getDehydratedQuery({ queryKey, queryFn });

  return (
    <main>
      {/* HydrationBoundary ์ปดํฌ๋„ŒํŠธ๋Š” ํด๋ผ์ด์–ธํŠธ์ธก์—์„œ dehydrated๋œ ์ฟผ๋ฆฌ๋“ค์„ ์—ญ์ง๋ ฌํ™” ์‹œ์ผœ hydration ๊ณผ์ •์—์„œ ์ดˆ๊ธฐ ์ฟผ๋ฆฌ๋“ค๋กœ ์‚ฌ์šฉ */}
      <HydrationBoundary state={{ queries: [query] }}>{children}</HydrationBoundary>
    </main>
  );
}

Caching Life Cycle

  • fresh

query์— ์„ค์ •๋œ staleTime์ด ์ง€๋‚˜์ง€ ์•Š์€ ์ƒํƒœ์ด๋ฉฐ, fresh ์ƒํƒœ์—์„œ๋Š” refetchingํ•˜์ง€ ์•Š์œผ๋ฉฐ ์บ์‹ฑ๋œ ์ฟผ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

  • fetching

queryFn์ด ์‹คํ–‰์ค‘์ธ ์ƒํƒœ์ž…๋‹ˆ๋‹ค.

  • stale

query์— ์„ค์ •๋œ staleTime์ด ์ง€๋‚ฌ์œผ๋ฉฐ ์ด๋Š” refetchingํ•˜์—ฌ ์ƒˆ๋กœ์šด ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ ์บ์‹ฑํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์ด๋•Œ refetchingํ•˜๋Š” ๋™์•ˆ์—๋Š” ๊ธฐ์กด stale ์ƒํƒœ์˜ ์ฟผ๋ฆฌ๋ฅด ์‚ฌ์šฉํ•˜๋ฉฐ ์ดํ›„ refething์ด ์™„๋ฃŒ๋˜๋ฉด ์ƒˆ๋กœ์šด ๋ฐ์ดํ„ฐ๋กœ ๊ต์ฒดํ•˜๊ณ  ์ด๋ฅผ ์บ์‹ฑํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

  • inactive

์ฟผ๋ฆฌ๊ฐ€ ์‹คํ–‰๋œ ์ปดํฌ๋„ŒํŠธ๊ฐ€ unmount๋˜๋Š” ๊ฒฝ์šฐ ํ•ด๋‹น ์ฟผ๋ฆฌ๋Š” inactive ์ƒํƒœ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. inactive ์ƒํƒœ๋Š” ์‚ฌ์šฉ๋˜์ง€๋Š” ์•Š์ง€๋งŒ ๋ฉ”๋ชจ๋ฆฌ์ƒ ์•„์ง ์บ์‹ฑ๋˜์–ด ์žˆ๋Š” ์ƒํƒœ์ž…๋‹ˆ๋‹ค.

  • delete

inactive ์ƒํƒœ์ธ ์ฟผ๋ฆฌ์— ์„ค์ •๋œ gcTime์ด ์ง€๋‚œ ์ƒํƒœ์ด๋ฉฐ ์ด๋Š” ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ์— ์˜ํ•ด ๋ฉ”๋ชจ๋ฆฌ์ƒ์—์„œ ์ œ๊ฑฐ๋ฉ๋‹ˆ๋‹ค.

useQuery

import { useQuery } from 'react-query';

async function fetchData() {
  return fetch('https://,,,', { method: 'GET' });
}

const {
  data, // queryFn์ด ๋ฐ˜ํ™˜ํ•œ ๊ฐ’, ์ดˆ๊ธฐ queryFn ์‹คํ–‰์ด ์™„๋ฃŒ๋˜๊ธฐ ์ „์—๋Š” undefined ๋ฐ˜ํ™˜
  dataUpdatedAt, // ๋งˆ์ง€๋ง‰์œผ๋กœ fetchingํ•œ ํƒ€์ž„์Šคํƒฌํ”„
  error, // queryFn ์‹คํ–‰ ์ค‘ ์—๋Ÿฌ ๋ฐœ์ƒํ•œ ๊ฒฝ์šฐ ์—๋Ÿฌ ๊ฐ์ฒด๊ฐ€ ๋ฐ”์ธ๋”ฉ
  isError, // queryFn ์‹คํ–‰ ์ค‘ ์—๋Ÿฌ ๋ฐœ์ƒ ์—ฌ๋ถ€
  errorUpdateCount, // ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒฃํ•˜๊ธฐ ๊นŒ์ง€์˜ queryFn ์‹คํ–‰ ํšŸ์ˆ˜
  errorUpdatedAt, // ๋งˆ์ง€๋ง‰์œผ๋กœ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ ํƒ€์ž„์Šคํƒฌํ”„
  failureCount, // ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ ํšŸ์ˆ˜
  failureReason, // ๋งˆ์ง€๋ง‰์œผ๋กœ ๋ฐœ์ƒํ•œ ์—๋Ÿฌ์˜ ๋ฉ”์„ธ์ง€ ํ˜น์€ ๊ฐ์ฒด
  fetchStatus, // ํ–”์ œ queryFn ์‹คํ–‰ ์ƒํƒœ ๋ฐ˜ํ™˜(idle, fetching, pause)
  isFetched, // queryFn์ด ์„ฑ๊ณต์ ์œผ๋กœ ์‹คํ–‰๋˜์—ˆ๋Š”์ง€ ์—ฌ๋ถ€
  isFetchedAfterMount, // ๋งˆ์šดํŠธ๋œ ์ดํ›„ queryFn์ด ์„ฑ๊ณต์ ์œผ๋กœ ์‹คํ–‰๋˜์—ˆ๋Š”์ง€ ์—ฌ๋ถ€
  isFetching, // queryFn์ด ํ˜„์žฌ ์‹คํ–‰์ค‘์ธ์ง€ ์—ฌ๋ถ€
  isLoading, // queryFn์ด ์ฒซ ์‹คํ–‰์ด๋ฉฐ ํ˜„์žฌ ์‹คํ–‰์ค‘์ธ์ง€ ์—ฌ๋ถ€
  isLoadingError, // queryFn ์ฒซ ์‹คํ–‰์ค‘ ์—๋Ÿฌ ๋ฐœ์ƒ ์—ฌ๋ถ€
  isPaused, // queryFn ์ผ์‹œ ์ค‘์ง€ ์—ฌ๋ถ€
  isPending, // queryFn ์‹คํ–‰ ๋Œ€๊ธฐ์ค‘ ์—ฌ๋ถ€(isFetching๊ณผ ์œ ์‚ฌํ•˜์ง€๋งŒ ๋” ํฌ๊ด„์ )
  isPlaceholderData, // ํ˜„์žฌ data๊ฐ€ placeholder ๋ฐ์ดํ„ฐ์ธ์ง€ ์—ฌ๋ถ€
  isRefetchError, // refetching ๋„์ค‘ ์—๋Ÿฌ ๋ฐœ์ƒ ์—ฌ๋ถ€
  isRefetching, // ํ˜„์žฌ refetching ์ค‘์ธ์ง€ ์—ฌ๋ถ€
  isStale, // ์บ์‹ฑ ์ƒํƒœ๊ฐ€ stale์ธ์ง€ ์—ฌ๋ถ€
  isSuccess, // queryFn์ด ์„ฑ๊ณต์ ์œผ๋กœ ์‹คํ–‰๋˜์—ˆ๋Š”์ง€ ์—ฌ๋ถ€
  refetch, // ์ˆ˜๋™์œผ๋กœ refetchingํ•˜๋Š” ํ•จ์ˆ˜
  status // ํ˜„์žฌ ์ฟผ๋ฆฌ ์ƒํƒœ๋ฅผ ๋ฐ˜ํ™˜(idle, loading, error, success)
} = useQuery({
  /**
   * queryKey๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์บ์‹ฑ ๊ด€๋ฆฌ๋˜๋ฉฐ ๋งŒ์•ฝ queryFn ํ•จ์ˆ˜ ๋‚ด์—์„œ ํŠน์ • ๋ณ€์ˆ˜์—
   * ์˜์กดํ•˜๊ณ  ์žˆ๋‹ค๋ฉด queryKey ๋ฐฐ์—ด ์š”์†Œ๋กœ ์ถ”๊ฐ€ํ•ด์ฃผ์–ด์•ผ ํ•จ.
   * **/
  queryKey: ['queryKey'],
  queryFn: fetchData // Promise ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜ ์ž‘์„ฑ
});

useQueries

import { useQueries } from 'react-query';

async function fetchData1() {
  return fetch('https://,,,', { method: 'GET' });
}

async function fetchData2() {
  return fetch('https://,,,', { method: 'GET' });
}

/**
 * useQueries ํ›…์€ ์—ฌ๋Ÿฌ ์ฟผ๋ฆฌ๋“ค์„ ๋ณ‘๋ ฌ๋กœ ์š”์ฒญํ•˜๊ณ 
 * ๋ชจ๋“  ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ๊ฐ€ ํฌํ•จ๋œ ๋ฐฐ์—ด์„ ๋ฐ˜ํ™˜
 * **/
const queryResults = useQueries({
  queries: [
    {
      queryKey: ['fetchData1'],
      queryFn: fetchData1
    },
    {
      queryKey: ['fetchData2'],
      queryFn: fetchData2
    }
  ]
});

useSuspenseQuery

useSuspenseQuery ํ›…์€ Suspense์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋ฉด ์ฟผ๋ฆฌ ์ƒํƒœ(status)๊ฐ€ loading์ธ ๊ฒฝ์šฐ Suspense์˜ fallback props์— ์„ค์ •ํ•œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ‘œ์‹œํ•ด์ค๋‹ˆ๋‹ค.

import { useSuspenseQuery } from 'react-query';

export default function Child() {
  async function fetchData() {
    return fetch('https://,,,', { method: 'GET' });
  }

  const queryResult = useSuspenseQuery({
    queryKey: ['queryKey'],
    queryFn: fetchData
  });

  return <div>{/* ,,, */}</div>;
}
import { Suspense } from 'react';

export default function Parent() {
  return (
    <Suspense fallback={<div>loading,,,</div>}>
      <Child />
    </Suspense>
  );
}

useInfiniteQuery

useInfiniteQuery ํ›…์€ ํŠน์ • ์กฐ๊ฑด์—์„œ ์ถ”๊ฐ€์ ์ธ ๋ฐ์ดํ„ฐ๋ฅผ fetching ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ด์ค๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๋ฌดํ•œ ์Šคํฌ๋กค ์ด๋‚˜ ํŽ˜์ด์ง• ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

import { useInfiniteQuery } from '@tanstack/react-query';

const {
  data: {
    pages, // ๋ชจ๋“  ํŽ˜์ด์ง€์˜ ๋ฐ์ดํ„ฐ๋ฅผ ํฌํ•จํ•˜๋Š” ๋ฐฐ์—ด
    pageParams // ๋ชจ๋“  ํŽ˜์ด์ง€์— ๋Œ€ํ•œ pageParam ๋ฐฐ์—ด
  },
  fetchNextPage, // ๋‹ค์Œ ํŽ˜์ด์ง€์˜ ๋ฐ์ดํ„ฐ๋ฅผ fetchingํ•˜๋Š” ํ•จ์ˆ˜์ด๋ฉฐ, ํ˜ธ์ถœ์‹œ queryFn์ด ์‹คํ–‰
  fetchPreviousPage, // ์ด์ „ ํŽ˜์ด์ง€์˜ ๋ฐ์ดํ„ฐ๋ฅผ fethcingํ•˜๋Š” ํ•จ์ˆ˜
  hasNextPage, // ๋‹ค์Œ ํŽ˜์ด์ง€ ์กด์žฌ ์—ฌ๋ถ€๋ฅผ ๋ฐ˜ํ™˜. ํ•ด๋‹น ๊ฐ’์€ getNextPageParam ํ•จ์ˆ˜๊ฐ€ undefined์ธ ๊ฒฝ์šฐ true ๋ฐ˜ํ™˜
  hasPreviousPage, // ์ด์ „ ํŽ˜์ด์ง€์˜ ์กด์žฌ ์—ฌ๋ถ€ ๋ฐ˜ํ™˜. getPreviousPageParam ํ•จ์ˆ˜๊ฐ€ undefined์ธ ๊ฒฝ์šฐ true ๋ฐ˜ํ™˜
  isFetchingNextPage, // ๋‹ค์Œ ํŽ˜์ด์ง€์˜ ๋ฐ์ดํ„ฐ๋ฅผ fetching ์ค‘์ธ์ง€ ์—ฌ๋ถ€๋ฅผ ๋ฐ˜ํ™˜
  isFetchingPreviousPage, // ์ด์ „ ํŽ˜์ด์ง€์˜ ๋ฐ์ดํ„ฐ๋ฅผ fetching ์ค‘์ธ์ง€ ์—ฌ๋ถ€๋ฅผ ๋ฐ˜ํ™˜
  ...result
} = useInfiniteQuery({
  queryKey, // ์ฟผ๋ฆฌ๋ฅผ ๊ณ ์œ ํ•˜๊ฒŒ ์‹๋ณ„ํ•˜๋Š” ํ‚ค
  queryFn: ({ pageParam }) => fetchPage(pageParam), // ๋ฐ์ดํ„ฐ๋ฅผ fetchingํ•˜๋Š” ๋น„๋™๊ธฐ ํ•จ์ˆ˜, ์ธ์ˆ˜๋กœ pageParam ์ „๋‹ฌ๋ฐ›์•„ ์‹คํ–‰
  initialPageParam: 1, // ์ดˆ๊ธฐ pageParam ๊ฐ’
  getNextPageParam: (lastPage, allPages, lastPageParam, allPageParams) => lastPage.nextCursor, // ๋‹ค์Œ ํŽ˜์ด์ง€์˜ queryFn ํ•จ์ˆ˜ pageParam ๊ฐ’ ๋ฐ˜ํ™˜. ์ธ์ˆ˜๋กœ ํ˜„์žฌ ํŽ˜์ด์ง€์˜ ๋ฐ์ดํ„ฐ, ์ „์ฒด ํŽ˜์ด์ง€์˜ ๋ฐ์ดํ„ฐ ๋ฐฐ์—ด, ํ˜„์žฌ ํŽ˜์ด์ง€์˜ pageParam, ์ „์ฒด ํŽ˜์ด์ง€์˜ pageParam ๋ฐฐ์—ด์„ ์ „๋‹ฌ๋ฐ›์•„ ์‹คํ–‰
  getPreviousPageParam: (firstPage, allPages, firstPageParam, allPageParams) => firstPage.prevCursor // ์ด์ „ ํŽ˜์ด์ง€์˜ queryFn ํ•จ์ˆ˜ pageParam ๊ฐ’ ๋ฐ˜ํ™˜
});

useMutation

useMutation ํ›…์€ ์ฃผ๋กœ ๋ฐ์ดํ„ฐ ์ƒ์„ฑ, ์ˆ˜์ •, ์‚ญ์ œ์™€ ๊ฐ™์€ ๋ณ€์ด ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•  ๋•Œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. useMutation์„ ํ†ตํ•ด ๋น„๋™๊ธฐ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๊ณ , ํ•ด๋‹น ์ž‘์—…์˜ ์ƒํƒœ๋ฅผ ์ถ”์ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

import { useMutation } from '@tanstack/react-query';

const {
  data, // mutationFn ์‹คํ–‰์ด ์™„๋ฃŒ๋˜์–ด ๋ฐ˜ํ™˜ํ•œ ๋ฐ์ดํ„ฐ
  error, // mutationFn ์‹คํ–‰ ์ค‘ ๋ฐœ์ƒํ•œ ์—๋Ÿฌ ๊ฐ์ฒด
  isError, // mutationFn ์‹คํ–‰ ์‹คํŒจ ์—ฌ๋ถ€๋ฅผ ๋ฐ˜ํ™˜
  isIdle, // mutationFn ์‹คํ–‰ ์ „์ธ์ง€์— ๋Œ€ํ•œ ์—ฌ๋ถ€๋ฅผ ๋ฐ˜ํ™˜
  isPending, // mutationFn ์‹คํ–‰ ๋Œ€๊ธฐ์ค‘์ด๊ฑฐ๋‚˜ ์‹คํ–‰์ค‘์ธ์ง€์— ๋Œ€ํ•œ ์—ฌ๋ถ€๋ฅผ ๋ฐ˜ํ™˜
  isPaused, // mutationFn ์‹คํ–‰์˜ ์ค‘์ง€ ์—ฌ๋ถ€๋ฅผ ๋ฐ˜ํ™˜
  isSuccess, // mutationFn ์‹คํ–‰ ์„ฑ๊ณต์ ์œผ๋กœ ์™„๋ฃŒ๋˜์—ˆ๋Š”์ง€์— ๋Œ€ํ•œ ์—ฌ๋ถ€
  failureCount, // mutationFn ์‹คํ–‰ ์‹คํŒจํ•œ ํšŸ์ˆ˜
  failureReason, // mutationFn ๋งˆ์ง€๋ง‰์— ์‹คํ–‰ ์‹คํŒจํ•œ ์—๋Ÿฌ ๊ฐ์ฒด
  mutate, // mutate ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ ์‹œ mutationFn ์‹คํ–‰
  mutateAsync, // mutateAsync ํ˜ธ์ถœ ์‹œ Promise ๊ฐ์ฒด ๋ฐ˜ํ™˜ํ•˜๋Š” mutationFn ์‹คํ–‰
  reset, // mutationFn ์‹คํ–‰ ์ƒํƒœ ์ดˆ๊ธฐํ™” ๋ฉ”์„œ๋“œ(data, error, isSuccess, isError ๋“ฑ ์ดˆ๊ธฐํ™”)
  status, // mutationFn ์‹คํ–‰ ์ƒํƒœ(idle, pending, error, success) ๋ฐ˜ํ™˜
  submittedAt, // mutationFn ์ฒ˜์Œ ์‹คํ–‰๋œ ํƒ€์ž„์Šคํƒฌํ”„ ๋ฐ˜ํ™˜
  variables // ๋งˆ์ง€๋ง‰ mutate ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ ์‹œ ์ „๋‹ฌํ•œ ๋ณ€์ˆ˜ ๋ฐ˜ํ™˜
} = useMutation({
  mutationFn, // ์‹ค์ œ ๋ณ€์ด ์ž‘์—… ์ˆ˜ํ–‰ํ•˜๋Š” ํ•จ์ˆ˜
  gcTime, // ๋ณ€์ด ์ž‘์—… ์บ์‹œ๊ฐ€ GC ๋˜๊ธฐ๊นŒ์ง€์˜ ์‹œ๊ฐ„(๋ฐ€๋ฆฌ์ดˆ)
  meta, // ๋ณ€์ด ์ž‘์—…์— ์ถ”๊ฐ€์ ์œผ๋กœ ์ „๋‹ฌํ•  ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ
  mutationKey, // ๋ณ€์ด ์ž‘์—…์„ ๊ณ ์œ ํ•˜๊ฒŒ ์‹๋ณ„ํ•˜๋Š” ํ‚ค ๊ฐ’
  networkMode, // ๋„คํŠธ์›ŒํŠธ ์ƒํƒœ์— ๋”ฐ๋ฅธ ๋ณ€์ด ์ž‘์—… ์ฒ˜๋ฆฌ ์„ค์ •
  onError, // ๋ณ€์ด ์ž‘์—… ์‹คํŒจ์‹œ ํ˜ธ์ถœ๋˜๋Š” ์ฝœ๋ฐฑ ํ•จ์ˆ˜. error, variables, context๋ฅผ ์ธ์ž๋กœ ์ „๋‹ฌ ๋ฐ›์•„ ์‹คํ–‰
  onMutate, // ๋ณ€์ด ์ž‘์—… ์‹คํ–‰ ์ „์— ํ˜ธ์ถœ๋˜๋Š” ์ฝœ๋ฐฑ ํ•จ์ˆ˜
  onSettled, // ๋ณ€์ด ์ž‘์—… ์„ฑ๊ณตํ•˜๊ฑฐ๋‚˜ ์‹คํŒจํ•œ ํ›„์— ํ•ญ์ƒ ํ˜ธ์ถœ๋˜๋Š” ์ฝœ๋ฐฑ ํ•จ์ˆ˜. data, error, variables, context ์ธ์ž ์ „๋‹ฌ ๋ฐ›์•„ ์‹คํ–‰
  onSuccess, // ๋ณ€์ด ์ž‘์—… ์„ฑ๊ณต์ ์œผ๋กœ ์™„๋ฃŒ๋œ ํ›„ ํ˜ธ์ถœ๋˜๋Š” ์ฝœ๋ฐฑ ํ•จ์ˆ˜. data, variables, context ์ธ์ž ์ „๋‹ฌ ๋ฐ›์•„ ์‹คํ–‰
  retry, // ๋ณ€์ด ์ž‘์—… ์‹คํŒจํ–ˆ์„ ๋•Œ ์žฌ์‹œ๋„ํ•  ํšŸ์ˆ˜
  retryDelay, // ๋ณ€์ด ์ž‘์—… ์‹คํŒจํ–ˆ์„ ๋•Œ ์žฌ์‹œ๋„ํ•˜๊ธฐ ์ „ ๋Œ€๊ธฐํ•  ์‹œ๊ฐ„(๋ฐ€๋ฆฌ์ดˆ)
  scope, // ๋ณ€์ด ์ž‘์—… ๋ฒ”์œ„ ์ง€์ •
  throwOnError // true ์„ค์ • ์‹œ ๋ณ€์ด ์ž‘์—… ์ค‘ ์—๋Ÿฌ ๋ฐœ์ƒํ•œ ๊ฒฝ์šฐ ์—๋Ÿฌ๋ฅผ throwํ•˜์—ฌ ํ˜ธ์ถœ์ž์—๊ฒŒ ์ „๋‹ฌ
});

About

fetching, caching, synchronizing and updating server state in your web applications (version 5, WIP) ๐Ÿ“ก

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published