๐Ÿ‘€ Suspensive v2์—์„œ์˜ ๋ณ€๊ฒฝ์„ ํ™•์ธํ•˜์„ธ์š”. ๋”๋ณด๊ธฐ โ†’
๋ฌธ์„œ๋ณด๊ธฐ@suspensive/react-queryqueryOptions

queryOptions

TanStack Query์˜ ๋ฉ”์ธํ…Œ์ด๋„ˆ Tkdodo์˜ TanStack Query v5์˜ queryOptions ์„ค๋ช… ์˜์ƒ์—์„œ ์ด interface๊ฐ€ ํ•„์š”ํ•œ ์ด์œ ๋ฅผ ์ž˜ ์„ค๋ช…๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. TanStack Query v4์—์„œ๋„ queryOptions๋ฅผ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  1. queryKey์™€ queryFn์„ ๋ฌถ์–ด์„œ ์ฒ˜๋ฆฌํ•ด queryKey๊ด€๋ฆฌ๊ฐ€ ์‰ฌ์›Œ์ง‘๋‹ˆ๋‹ค.
  2. ๋ถˆํ•„์š”ํ•œ ์ปค์Šคํ…€ ์ฟผ๋ฆฌ ํ›…์„ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. TanStack Query v4์˜ useQuery, useQueries, Suspensive React Query์˜ useSuspenseQuery, useSuspenseQueries, SuspenseQuery์— ๋ชจ๋‘ ์ง์ ‘ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.
  3. TanStack Query v5์—๋Š” ์ด๋ฏธ queryOptions๊ฐ€ ์ œ๊ณต๋˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— TanStack Query v4์—์„œ TanStack Query v5๋กœ์˜ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์ด ์‰ฌ์›Œ์ง‘๋‹ˆ๋‹ค.
import { queryOptions, useSuspenseQuery, useSuspenseQueries, SuspenseQuery } from '@suspensive/react-query'
import { useQuery, useQueries, useQueryClient } from '@tanstack/react-query'
 
const postQueryOptions = (postId) =>
  queryOptions({
    queryKey: ['posts', postId] as const,
    queryFn: ({
      queryKey: [, postId], // queryKey๋ฅผ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    }) => fetch(`https://example.com/posts/${postId}`),
  })
 
// ์ปค์Šคํ…€ ์ฟผ๋ฆฌ ํ›…์„ ๋งŒ๋“ค ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.
// useQuery, useQueries, useSuspenseQuery, useSuspenseQueries, SuspenseQuery์—์„œ ์ง์ ‘ queryOptions๋ฅผ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
const post1Query = useQuery(postQueryOptions(1))
const { data: post1 } = useSuspenseQuery({
  ...postQueryOptions(1),
  refetchInterval: 2000, // ์‚ฌ์šฉ์ฒ˜์—์„œ ํ™•์žฅ์„ฑ์„ ๋ช…ํ™•ํžˆ ํ‘œํ˜„๋ฉ๋‹ˆ๋‹ค.
})
const [post1Query, post2Query] = useQueries({
  queries: [postQueryOptions(1), { ...postQueryOptions(2), refetchInterval: 2000 }],
})
const [{ data: post1 }, { data: post2 }] = useSuspenseQueries({
  queries: [postQueryOptions(1), { ...postQueryOptions(2), refetchInterval: 2000 }],
})
const Example = () => <SuspenseQuery {...postQueryOptions(1)}>{({ data: post1 }) => <>{post1.text}</>}</SuspenseQuery>
 
// queryClient์˜ ๋ฉ”์†Œ๋“œ์—์„œ queryKey์™€ queryFn์„ ์‰ฝ๊ฒŒ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
const queryClient = useQueryClient()
queryClient.refetchQueries(postQueryOptions(1))
queryClient.prefetchQuery(postQueryOptions(1))
queryClient.invalidateQueries(postQueryOptions(1))
queryClient.fetchQuery(postQueryOptions(1))
queryClient.resetQueries(postQueryOptions(1))
queryClient.cancelQueries(postQueryOptions(1))
 
import { Suspense } from '@suspensive/react'
import { queryOptions, SuspenseQuery } from '@suspensive/react-query'
import { useQueryClient } from '@tanstack/react-query'
import { getPost } from './api'

const postQueryOptions = (postId: number) =>
  queryOptions({
    queryKey: ['posts', postId],
    queryFn: () => getPost(postId),
  })

export const Example = () => {
  const queryClient = useQueryClient()

  return (
    <div>
      <button onClick={() => queryClient.resetQueries(postQueryOptions(1))}>
        Reset Query
      </button>
      <Suspense fallback={<div>Loading...</div>}>
        <SuspenseQuery {...postQueryOptions(1)}>
          {({ data }) => {
            return (
              <div>
                <h1>{data.title}</h1>
                <p>{data.body}</p>
              </div>
            )
          }}
        </SuspenseQuery>
      </Suspense>
    </div>
  )
}