๋ฆฌ์•กํŠธ ์ฟผ๋ฆฌ ํ•˜์ด๋“œ๋ ˆ์ด์…˜์—์„œ fetchQuery๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ์ด์œ 

 

 

ํ”„๋กœ์ ํŠธ์—์„œ React Query์˜ Hydration๊ณผ prefetchQuery๋ฅผ ํ™œ์šฉํ•˜์—ฌ SSR(Server-Side Rendering)์„ ๊ตฌํ˜„ํ–ˆ๋‹ค.

https://new-development.tistory.com/13

 

React Query์™€ SSR: ์„œ๋ฒ„ ์‚ฌ์ด๋“œ ๋ฐ์ดํ„ฐ ๊ด€๋ฆฌ์™€ Hydration ํ™œ์šฉ

ํ˜„์žฌ ํ”„๋กœ์ ํŠธ๋Š” ์„œ๋ฒ„ ์‚ฌ์ด๋“œ ๋ Œ๋”๋ง(SSR)๊ณผ ํด๋ผ์ด์–ธํŠธ ์‚ฌ์ด๋“œ ๋ Œ๋”๋ง(CSR)์ด ํ˜ผํ•ฉ๋œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด๋‹ค.์ •์ ์ธ ํŽ˜์ด์ง€: ๋ฐ์ดํ„ฐ ๋ณ€ํ™”๊ฐ€ ์ ์–ด ์ •์  ์ฝ˜ํ…์ธ ๋กœ ์ œ๊ณต (e.g. ๋ฉ”์ธ ํ™”๋ฉด)๋™์ ์ธ ํŽ˜์ด์ง€: ๋ฐ

new-development.tistory.com

 

 

์ด ๊ณผ์ •์—์„œ ํŒ€์›๋“ค๊ณผ ๋‹ค์–‘ํ•œ ์˜๊ฒฌ์„ ๋‚˜๋ˆด๋Š”๋ฐ, ๊ทธ์ค‘ fetchQuery์— ๋Œ€ํ•œ ๋…ผ์˜๊ฐ€ ์žˆ์—ˆ๋‹ค.

์˜๊ฒฌ 1.
"๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์—์„œ SSR์„ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ํŒจ์นญํ•œ ๋’ค, ์ด๋ฅผ ์ž์‹ ์ปดํฌ๋„ŒํŠธ์— props๋กœ ์ „๋‹ฌํ•˜๋ฉด ์ž์‹ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋กœ ๋™์ž‘ํ•  ์ˆ˜ ์žˆ์ง€ ์•Š์„๊นŒ์š”? SEO ๊ด€์ ์—์„œ ๋” ์œ ๋ฆฌํ•  ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค."

์˜๊ฒฌ 2.
"fetchQuery๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์™€ props๋กœ ๋„˜๊ฒจ์ฃผ๋Š” ๋ฐฉ์‹์€ ์–ด๋–จ๊นŒ์š”? ์†๋„๋ฉด์—์„œ ์žฅ์ ์ด ์žˆ์„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค."

 

์ด ๋…ผ์˜์—์„œ ๋‚˜๋Š” ๋ฆฌ์•กํŠธ์ฟผ๋ฆฌ ๊ณต์‹ ๋ฌธ์„œ๊ฐ€ prefetchQuery์™€ useQuery๋ฅผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ ์— ์˜๋ฌธ์ด ๋“ค์–ด ๊ด€๋ จ ๋‚ด์šฉ์„ ์กฐ์‚ฌํ•˜๊ณ  ์ •๋ฆฌํ–ˆ๋‹ค.

 

 


 

 

 

fetchQuery์˜ ๋ฌธ์ œ์ 

์˜ˆ์ œ ์ฝ”๋“œ

// fetchQuery ์‚ฌ์šฉ ์˜ˆ์‹œ
const ParentComponent = async () => {
  const data = await fetchQuery(queryClient, ['posts'], fetchPosts);
  return <ChildComponent posts={data} />;
};

 

๋ฌธ์ œ 1: ์บ์‹œ ์ง€์†์„ฑ ๋ถ€์กฑ
fetchQuery๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์™€ ์ฆ‰์‹œ ์‚ฌ์šฉํ•˜๋Š” ์ผํšŒ์„ฑ ์ž‘์—…์— ์ ํ•ฉํ•˜๋‹ค. ํ•˜์ง€๋งŒ React Query์˜ ์บ์‹œ์™€ ์™„๋ฒฝํžˆ ํ†ตํ•ฉ๋˜์ง€ ์•Š์•„ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.

  • ๋ฐ์ดํ„ฐ๊ฐ€ ์บ์‹œ๋˜๋”๋ผ๋„ ๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ์—์„œ ์ด๋ฅผ ํ™œ์šฉํ•˜์ง€ ๋ชปํ•จ.
  • ์ƒˆ๋กœ๊ณ ์นจ, ํŽ˜์ด์ง€ ์ด๋™ ์‹œ ์บ์‹œ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์žƒ์–ด๋ฒ„๋ฆผ.

 

๋ฌธ์ œ 2: ๋ฆฌํŒจ์นญ ๋ฌธ์ œ
fetchQuery๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜จ ํ›„, ์ž์‹ ์ปดํฌ๋„ŒํŠธ์—์„œ useQuery๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋™์ผํ•œ ์ฟผ๋ฆฌ ํ‚ค์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ์ค‘๋ณต ์š”์ฒญ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.

const ChildComponent = ({ posts }) => {
  // ๋ถˆํ•„์š”ํ•œ ๋„คํŠธ์›Œํฌ ์š”์ฒญ ๋ฐœ์ƒ ๊ฐ€๋Šฅ
  const { data } = useQuery(['posts'], fetchPosts);
  return <div>{/* ... */}</div>;
};

 

๋ฌธ์ œ 3: React Query์˜ ๊ณ ๊ธ‰ ๊ธฐ๋Šฅ ํ™œ์šฉ ์ œํ•œ
React Query์˜ ๊ณ ๊ธ‰ ๊ธฐ๋Šฅ๋“ค์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค.

  • ๋ฐ์ดํ„ฐ ์‹ ์„ ๋„ ๊ด€๋ฆฌ
  • ์ž๋™ ๋ฐฑ๊ทธ๋ผ์šด๋“œ ๋ฆฌํŒจ์นญ
  • ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฐ ์žฌ์‹œ๋„
  • ๋‚™๊ด€์  ์—…๋ฐ์ดํŠธ Optimistic UI

 


prefetchQuery์™€ useQuery์˜ ์กฐํ•ฉ

prefetchQuery๋Š” SSR์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฏธ๋ฆฌ ๊ฐ€์ ธ์™€ React Query ์บ์‹œ์— ์ €์žฅํ•˜๊ณ , ํด๋ผ์ด์–ธํŠธ์—์„œ ์ด๋ฅผ ํ™œ์šฉํ•ด Hydration์„ ์ˆ˜ํ–‰ํ•œ๋‹ค. ์ด ๋ฐฉ์‹์€ fetchQuery์˜ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋ฉฐ, ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ด์ ์„ ์ œ๊ณตํ•œ๋‹ค.

  • ๋ฐ์ดํ„ฐ ์‹ ์„ ๋„ ๊ด€๋ฆฌ: staleTime๊ณผ cacheTime ์„ค์ • ๊ฐ€๋Šฅ
  • ์บ์‹œ ํ™œ์šฉ: ์—ฌ๋Ÿฌ ์ปดํฌ๋„ŒํŠธ์—์„œ ๋™์ผํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ณต์œ 
  • ์„ฑ๋Šฅ ์ตœ์ ํ™”: ๋ถˆํ•„์š”ํ•œ ๋„คํŠธ์›Œํฌ ์š”์ฒญ ๋ฐฉ์ง€
  • ์œ ์ง€๋ณด์ˆ˜ ์šฉ์ด์„ฑ: React Query์˜ ์ƒํƒœ ๊ด€๋ฆฌ ๊ธฐ๋Šฅ์„ ์ ๊ทน ํ™œ์šฉ

 


์‹ค์ œ ํ”„๋กœ์ ํŠธ ์ ์šฉ

  1. ๋ฉ”์ธ ํŽ˜์ด์ง€
  • ์‹ค์‹œ๊ฐ„์„ฑ์ด ์ค‘์š”ํ•œ ์ธ๊ธฐ ์—ฌํ–‰/๋ฆฌ๋ทฐ ์ปดํฌ๋„ŒํŠธ์—์„œ prefetchQuery์™€ useQuery ์กฐํ•ฉ์„ ์‚ฌ์šฉํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ๊ด€๋ฆฌ
  • ์ด์œ : ๋ฐ์ดํ„ฐ ์‹ ์„ ๋„ ๊ด€๋ฆฌ๊ฐ€ ์ค‘์š”ํ•˜๋ฉฐ, React Query์˜ ์ž๋™ ๋ฆฌํŒจ์นญ ๊ธฐ๋Šฅ์„ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ
  1. ์ƒ์„ธ ํŽ˜์ด์ง€
  • ์—ฌํ–‰ ์ƒ์„ธ ํŽ˜์ด์ง€์ฒ˜๋Ÿผ ์ •์  ๋ฐ์ดํ„ฐ ์œ„์ฃผ์˜ ํ™”๋ฉด์—์„œ๋Š” fetchQuery๋ฅผ ์‚ฌ์šฉํ•ด๋„ ๋ฌด๋ฐฉํ•˜์ง€๋งŒ, ๋™์  ์š”์†Œ(์˜ˆ: ๋ถ๋งˆํฌ, ๋™ํ–‰ ์‹ ์ฒญ ๋ฒ„ํŠผ)์—์„œ๋Š” ๋ฐ์ดํ„ฐ ๋ถˆ์ผ์น˜ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ์–ด ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ prefetchQuery ์‚ฌ์šฉ

 


fetchQuery vs prefetchQuery: ์ •๋ฆฌ

์„ ํƒ๊ธฐ์ค€ fetchQuery prefetchQuery
๋ฐ์ดํ„ฐ ์„ฑ๊ฒฉ ์ •์  ๋ฐ์ดํ„ฐ ๋™์  ๋ฐ์ดํ„ฐ, ์‹ ์„ ๋„ ๊ด€๋ฆฌ ํ•„์š”
SEO ํ•„์š” ํ•„์š”
์บ์‹œ ํ™œ์šฉ ์ œํ•œ์  ํšจ๊ณผ์ 
React Query ๊ธฐ๋Šฅ ํ™œ์šฉ ๋ถˆ๊ฐ€๋Šฅ ๊ฐ€๋Šฅ

 

 

 


prefetchQuery์™€ SSR/CSR์— ๋Œ€ํ•œ ์˜๋ฌธ์ 

prefetchQuery๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ž์‹ ์ปดํฌ๋„ŒํŠธ๊ฐ€ useQuery๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋ฏ€๋กœ, ์ž์‹ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋˜์–ด SSR์ด ์ œ๋Œ€๋กœ ๋™์ž‘ํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ด ์•„๋‹Œ๊ฐ€?

 

SSR์ด ๋™์ž‘ํ•˜๋Š” ์ด์œ 

1. ์„œ๋ฒ„ ์—ญํ• 

  • ์„œ๋ฒ„๋Š” ํด๋ผ์ด์–ธํŠธ๊ฐ€ ํ•„์š”๋กœ ํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๋ฏธ๋ฆฌ ๊ฐ€์ ธ์™€ React Query์˜ ์บ์‹œ์— ์ €์žฅํ•œ๋‹ค.
  • ์ €์žฅ๋œ ์บ์‹œ๋Š” dehydrate๋ฅผ ํ†ตํ•ด JSON ํ˜•ํƒœ๋กœ ์ง๋ ฌํ™”๋œ๋‹ค. ์ด ์ง๋ ฌํ™”๋œ ๋ฐ์ดํ„ฐ๋Š” HTML์— ์‚ฝ์ž…๋˜์–ด ํด๋ผ์ด์–ธํŠธ๋กœ ์ „๋‹ฌ๋œ๋‹ค.

2. ์„œ๋ฒ„์—์„œ ์™„์ „ํ•œ HTML ์ œ๊ณต

  • ์„œ๋ฒ„์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฏธ๋ฆฌ ํŒจ์นญํ–ˆ๊ธฐ ๋•Œ๋ฌธ์—, ๋ธŒ๋ผ์šฐ์ €๋Š” ์ด ๋ฐ์ดํ„ฐ๋ฅผ ํฌํ•จํ•œ ์™„์ „ํ•œ HTML์„ ๋ฐ›์•„ ๊ฒ€์ƒ‰์—”์ง„์ด ์ด๋ฅผ ๋ฐ”๋กœ ์ฝ์„ ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

3. ์ดˆ๊ธฐ ๋ Œ๋”๋ง

  • ์ž์‹ ์ปดํฌ๋„ŒํŠธ๊ฐ€ useQuery๋ฅผ ์‚ฌ์šฉํ•˜๋”๋ผ๋„, ํด๋ผ์ด์–ธํŠธ๋Š” ์ด๋ฏธ Hydration์„ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด์œ ํ•˜๊ณ  ์žˆ๋‹ค. ์ฆ‰, ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๋Š” Hydration๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ฆ‰์‹œ ๋ Œ๋”๋งํ•˜๋ฏ€๋กœ ์ถ”๊ฐ€ ๋„คํŠธ์›Œํฌ ์š”์ฒญ์ด ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š”๋‹ค.

 

 


 

์ •๋ฆฌํ•˜๋‹ค๋ณด๋‹ˆ ๋ฌด์กฐ๊ฑด prefetchQuery๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” ๊ฒƒ ์ฒ˜๋Ÿผ ๋งํ–ˆ์ง€๋งŒ, ํ”„๋กœ์ ํŠธ์˜ ์ ํ•ฉ์„ฑ์— ๋”ฐ๋ผ ๊ณ ๋ คํ•ด์•ผ ํ•  ์ ์ด ๋งŽ์€ ๊ฒƒ ๊ฐ™๋‹ค.

 

 

 

์ฐธ๊ณ ์ž๋ฃŒ

fetchQuery vs prefetchQuery

 

fetchQuery vs prefetchQuery

fetchQuery vs prefetchQuery

jgjgill-blog.netlify.app

 

๊ณ ๊ธ‰ ์„œ๋ฒ„ ๋ Œ๋”๋ง

 

๊ณ ๊ธ‰ ์„œ๋ฒ„ ๋ Œ๋”๋ง

๊ณ ๊ธ‰ ์„œ๋ฒ„ ๋ Œ๋”๋ง ์ƒ์„ฑ์ผ: 2024-03-30 ์ˆ˜์ •์ผ: 2024-03-30 ์ด ๋ฌธ์„œ๋Š” React Query๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ŠคํŠธ๋ฆฌ๋ฐ, ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ, Next.js ์•ฑ ๋ผ์šฐํ„ฐ๋ฅผ ํ™œ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์†Œ๊ฐœํ•˜๋Š” ๊ณ ๊ธ‰ ์„œ๋ฒ„ ๋ Œ๋”๋ง ๊ฐ€์ด๋“œ๋‹ค. ์ด ๊ฐ€์ด

www.vigorously.xyz