๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
Frontend/TroubleShooting

[Trouble Shooting] React Query์˜ QueryClient๋ฅผ ๊ณตํ†ต๋ชจ๋“ˆ์—์„œ ์‹ฑ๊ธ€ํ†ค์œผ๋กœ ๊ด€๋ฆฌํ•˜๊ธฐ

by YWTechIT 2025. 12. 3.
728x90

๐Ÿ“ React Query์˜ QueryClient๋ฅผ ๊ณตํ†ต๋ชจ๋“ˆ์—์„œ ์‹ฑ๊ธ€ํ†ค์œผ๋กœ ๊ด€๋ฆฌํ•˜๊ธฐ

๋ฐฐ๊ฒฝ

ํ•ด์™ธ TNA NOL ๋‚ด์žฌํ™”๋ฅผ ๋งˆ์น˜๊ณ  NOL ๋„๋ฉ”์ธ๋‚ด์—์„œ๋„ ๋ฆฌ๋ทฐ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ณตํ†ต๋ชจ๋“ˆ์— ๋ฆฌ๋ทฐํŒจํ‚ค์ง€๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ์ž‘์—… ๋•Œ ๋งˆ์ฃผํ•œ ๊ณ ๋ฏผ์ด๋‹ค. ๋ฆฌ๋ทฐ๋Š” PDP(์ƒํ’ˆ ์ƒ์„ธ ํŽ˜์ด์ง€)์—์„œ ๋ฆฌ๋ทฐ ์กฐํšŒ, ์‹ ๊ณ ๊ฐ€ ๊ฐ€๋Šฅํ•˜๊ณ  (๋‚ด๊ฐ€ ์ž‘์„ฑํ•œ ๋ฆฌ๋ทฐ์˜ ๊ฒฝ์šฐ) ์ˆ˜์ •/์‚ญ์ œ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋ฉฐ ์˜ˆ์•ฝ ๋ชฉ๋ก/์ƒ์„ธ ํŽ˜์ด์ง€์—์„œ ์ž‘์„ฑ ๋ฐ ์ˆ˜์ •์ด ๊ฐ€๋Šฅํ•œ ๊ตฌ์กฐ์ด๋‹ค.

๋ฌธ์ œ ์ƒํ™ฉ

์˜ˆ์•ฝ ์ƒ์„ธ ํŽ˜์ด์ง€์—์„œ ๋ฆฌ๋ทฐ๋ฅผ ์ž‘์„ฑํ•˜๊ฑฐ๋‚˜ ์ˆ˜์ •ํ•œ ํ›„ PDP๋กœ ๋Œ์•„๊ฐ€๋ฉด, ์ถ”๊ฐ€/์ˆ˜์ •๋œ ๋‚ด์šฉ์ด ๋ฐ˜์˜๋˜์ง€ ์•Š๊ณ  ์ด์ „ ๋ฐ์ดํ„ฐ๊ฐ€ ๊ทธ๋Œ€๋กœ ๋…ธ์ถœ๋˜๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

 

์›์ธ ๋ถ„์„:

  • ๊ฐ ๋ฒ„ํ‹ฐ์ปฌ(PDP, ์˜ˆ์•ฝ ๋“ฑ)์ด ๋…๋ฆฝ์ ์ธ QueryClient ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.
  • ์˜ˆ์•ฝ ํŽ˜์ด์ง€์—์„œ queryClient.invalidateQueries()๋ฅผ ํ˜ธ์ถœํ•ด๋„, PDP์˜ QueryClient๋Š” ๋ณ„๋„ ์ธ์Šคํ„ด์Šค์ด๊ธฐ ๋•Œ๋ฌธ์— ์บ์‹œ ๋ฌดํšจํ™”๊ฐ€ ์ „ํŒŒ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.
  • ๊ฒฐ๊ณผ์ ์œผ๋กœ ๊ฐ ํŽ˜์ด์ง€๊ฐ€ ์„œ๋กœ ๋‹ค๋ฅธ ์บ์‹œ๋ฅผ ์ฐธ์กฐํ•˜๊ฒŒ ๋˜์–ด ๋ฐ์ดํ„ฐ ์ •ํ•ฉ์„ฑ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

๋Œ€์•ˆ ๋ถ„์„

  1. ๊ฐ ๋ฒ„ํ‹ฐ์ปฌ์˜ _app.tsx์—์„œ ๊ณตํ†ต Provider ์‚ฌ์šฉ

์žฅ์ :

  • ๋ช…์‹œ์ ์ด๊ณ  ์ œ์–ด ๊ฐ€๋Šฅํ•œ ๊ตฌ์กฐ

๋‹จ์ :

  • ๋ชจ๋“  ๋ฒ„ํ‹ฐ์ปฌ์—์„œ ๋™์ผํ•œ ๋ณด์ผ๋Ÿฌํ”Œ๋ ˆ์ดํŠธ ์ฝ”๋“œ ์ถ”๊ฐ€ ํ•„์š”
  • ์‹ค์ˆ˜๋กœ ๋ˆ„๋ฝํ•˜๋ฉด ๋ฐ์ดํ„ฐ ๋™๊ธฐํ™” ์‹คํŒจ
  1. ์‹ฑ๊ธ€ํ†ค ํŒจํ„ด์œผ๋กœ ์ „์—ญ QueryClient ๊ด€๋ฆฌ โœ…

์žฅ์ :

  • ๋ฒ„ํ‹ฐ์ปฌ์—์„œ ์ถ”๊ฐ€ ์„ค์ • ๋ถˆํ•„์š”
  • ๋ชจ๋“  ํŽ˜์ด์ง€๊ฐ€ ๋™์ผํ•œ ์บ์‹œ ์ฐธ์กฐ
  • ํ•œ ๊ณณ์—์„œ invalidate, refetchQueries ํ•ด๋„ ์ „์—ญ ๋ฐ˜์˜

๋‹จ์ :

  • ์ „์—ญ ์Šค์ฝ”ํ”„ ๋ณ€์ˆ˜ ์‚ฌ์šฉ์— ๋Œ€ํ•œ ์šฐ๋ ค๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ์œผ๋‚˜, ์ด๋Š” React Query ๊ณต์‹ ๋ฌธ์„œ์—์„œ๋„ ๊ถŒ์žฅํ•˜๋Š” ํŒจํ„ด (์ฐธ๊ณ )

์ฝ”๋“œ

 

// AS-IS
// ๋ฌธ์ œ ์ƒํ™ฉ: ๊ฐ ๋ฒ„ํ‹ฐ์ปฌ์ด ๋…๋ฆฝ์ ์ธ QueryClient ์ƒ์„ฑ
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { useState, type ReactNode } from 'react'

export function QueryClientProviders({ children }: { children: ReactNode }) {
  const [queryClient] = useState(
    () =>
      new QueryClient({
        defaultOptions: {
          queries: {
            staleTime: 60 * 1000,
            refetchOnWindowFocus: false,
            retryOnMount: false,
            retry: false,
          },
        },
      }),
  )

  return (
    <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
  )
}


// TO-BE
// nol-query-client.tsx

import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { useState, type ReactNode } from 'react'

let globalQueryClient: QueryClient | null = null

export function NolQueryClientProviders({ children }: { children: ReactNode }) {
  const [queryClient] = useState(getGlobalQueryClient)

  return (
    <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
  )
}

function getGlobalQueryClient() {
  if (!globalQueryClient) {
    globalQueryClient = new QueryClient({
      defaultOptions: {
        queries: {
          staleTime: 60 * 1000,
          refetchOnWindowFocus: false,
          retryOnMount: false,
          retry: false,
        },
      },
    })
  }
  return globalQueryClient
}

๊ฒฐ๋ก 

๊ธ‰ํ•œ ์ผ์ • ์†์—์„œ๋„ "์™œ ์ด ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋Š”๊ฐ€?"๋ฅผ ๋ถ„์„ํ•˜๊ณ , ์—ฌ๋Ÿฌ ๋Œ€์•ˆ์„ ๋น„๊ตํ•œ ๊ณผ์ •์ด ์ €์—๊ฒŒ๋Š” ๊ฐ€์น˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ์™„๋ฒฝํ•œ ํ•ด๊ฒฐ์ฑ…์€ ์—†์ง€๋งŒ, ํ˜„์žฌ ์ƒํ™ฉ์— ๊ฐ€์žฅ ์ ํ•ฉํ•œ ์„ ํƒ์„ ํ•  ์ˆ˜ ์žˆ๋˜ ๊ณ„๊ธฐ์˜€์Šต๋‹ˆ๋‹ค.

๋ฐ˜์‘ํ˜•

๋Œ“๊ธ€