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

QueryClientConsumer

โš ๏ธ

<QueryClientConsumer/>๋Š” ์‹คํ—˜ ๊ธฐ๋Šฅ์ด๋ฏ€๋กœ ์ด ์ธํ„ฐํŽ˜์ด์Šค๋Š” ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

React hook์˜ ์ œ์•ฝ์„ ํ”ผํ•ด JSX ์ƒ์—์„œ useQueryClient๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ์ž…๋‹ˆ๋‹ค.

์‚ฌ์šฉ์ž ํ™˜๊ฒฝ์— ์„ค์น˜๋˜์–ด ์žˆ๋Š” @tanstack/react-query์˜ ๋ฒ„์ „์— ๋”ฐ๋ผ props ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. @tanstack/react-query v4 ๋ฒ„์ „์ด ์„ค์น˜๋˜์–ด ์žˆ๋‹ค๋ฉด props.context๋ฅผ ์‚ฌ์šฉํ•˜๊ณ , v5๋ฒ„์ „ ์ด๋ฉด props.queryClient๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. props๋ฅผ ํ†ตํ•ด QueryClient๊ฐ€ ์ „๋‹ฌํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด, ์ปดํฌ๋„ŒํŠธ์™€ ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด QueryClient๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

import { useSuspenseQuery } from '@tanstack/react-query'
import { QueryClientConsumer } from '@suspensive/react-query'
 
const PostsPage = () => {
  const { data: posts } = useSuspenseQuery({
    queryKey: ['posts'],
    queryFn: () => getPosts(),
  })
 
  return (
    <>
      <QueryClientConsumer>
        {(queryClient) => (
          <button
            onClick={() =>
              queryClient.invalidateQueries({
                queryKey: ['posts'],
              })
            }
          >
            Posts refresh
          </button>
        )}
      </QueryClientConsumer>
      {posts.map((post) => (
        <Post key={post.id} {...post} />
      ))}
    </>
  )
}

props.queryClient (@tanstack/react-query v5)

@tanstack/react-query v5๊ฐ€ ์„ค์น˜๋œ ํ™˜๊ฒฝ์ด๋ผ๋ฉด props.queryClient ์‚ฌ์šฉํ•˜์—ฌ ์›ํ•˜๋Š” QueryClient์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

import { QueryClient } from '@tanstack/react-query'
import { QueryClientConsumer } from '@suspensive/react-query'
 
const queryClient = new QueryClient()
 
const Example = () => {
  return (
      {/* 5๏ธโƒฃ @tanstack/react-query v5์„ ์‚ฌ์šฉํ•˜์‹ ๋‹ค๋ฉด props.queryClient๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. */}
      <QueryClientConsumer queryClient={queryClient}>
        {(queryClient) => (<>{/* props.queryClient๋กœ ์ „๋‹ฌ๋œ QueryClinet๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. */}</>)}
      </QueryClientConsumer>
  )
}

props.context (@tanstack/react-query v4)

@tanstack/react-query v4๊ฐ€ ์„ค์น˜๋œ ํ™˜๊ฒฝ์ด๋ผ๋ฉด props.context๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์›ํ•˜๋Š” QueryClient์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

import { createContext } from 'react'
import { QueryClient } from '@tanstack/react-query'
import { QueryClientConsumer } from '@suspensive/react-query'
 
const queryClient = new QueryClient()
const queryClientContext = createContext<QueryClient>(queryClient)
 
const Example = () => {
  return (
      {/* 4๏ธโƒฃ @tanstack/react-query v4์„ ์‚ฌ์šฉํ•˜์‹ ๋‹ค๋ฉด props.context ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.*/}
      <QueryClientConsumer context={queryClientContext}>
        {(queryClient) => (<>{/* props.queryClient๋กœ ์ „๋‹ฌ๋œ QueryClinet๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. */}</>)}
      </QueryClientConsumer>
  )
}

๋™๊ธฐ: ๋ฆฌ์•กํŠธ ํ›…์€ ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ์—์„œ๋งŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•จ

React์˜ ํ›…(useQueryClient)์€ ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ์—์„œ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋ ˆ๊ฑฐ์‹œ ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ์—์„œ๋„ ์ฟผ๋ฆฌ ๋ฌดํšจํ™”(invalidateQueries)์™€ ๊ฐ™์€ ๊ธฐ๋Šฅ์ด ํ•„์š”ํ•  ๋•Œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋•Œ <QueryClientConsumer/>๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ด๋Ÿฌํ•œ ์ œ์•ฝ์„ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

import React from 'react'
import { QueryClientConsumer } from '@suspensive/react-query'
 
class PostsRefreshButton extends React.Component {
  render() {
    return (
      {/* โœ… ๋ ˆ๊ฑฐ์‹œ ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ์—์„œ queryClient๋ฅผ ์ ‘๊ทผํ•˜์—ฌ ์ฟผ๋ฆฌ ๋ฌดํšจํ™”(invalidateQueries)๋ฅผ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. */}
      <QueryClientConsumer>
        {(queryClient) => (
          <button
            onClick={() =>
              queryClient.invalidateQueries({
                queryKey: ['posts'],
              })
            }
          >
            Posts refresh
          </button>
        )}
      </QueryClientConsumer>
    )
  }
}
 
export default PostsRefreshButton