[Next JS] Anchoring issue :: SWR / react-query ์‚ฌ์šฉ ์‹œ ์ฃผ์˜ํ•  ์ 

 

์˜ค๋Š˜์€ Next JS์—์„œ Client Data fetching ์‚ฌ์šฉ ์‹œ ๋งˆ์ฃผํ•  ์ˆ˜ ์žˆ๋Š” Anchoring ์ด์Šˆ์— ๋Œ€ํ•ด ์ •๋ฆฌํ•˜๋ ค ํ•ฉ๋‹ˆ๋‹ค. Next JS docs์—์„œ ๊ถŒ์žฅํ•˜๊ณ  ์žˆ๋Š” ์ฝ”๋“œ ์Šคํƒ€์ผ์„ ์ ์šฉํ–ˆ์„ ๋•Œ ์ƒ๊ธธ ์ˆ˜ ์žˆ๋Š” ์ด์Šˆ์ด๊ธฐ ๋•Œ๋ฌธ์—, ๊ด€๋ จ ์ด์Šˆ๊ฐ€ ์ƒ๊ฒผ์„ ๋•Œ ์ €๋Š” ๋””๋ฒ„๊น…์— ์‹œ๊ฐ„์„ ๊ฝค๋‚˜ ์ผ์Šต๋‹ˆ๋‹ค. ๋จผ์ € Next JS์˜ Data fetching์— ๋Œ€ํ•œ ์ง€์‹์ด ์ „๋ฌดํ•  ๋ถ„๋“ค์„ ์œ„ํ•ด ๊ฐœ๋…๋ถ€ํ„ฐ ์ •๋ฆฌํ•˜๊ณ  ์ด์Šˆ์— ๋Œ€ํ•œ ํ•ด๊ฒฐ ๊ณผ์ •์„ ์ฐจ๋ก€๋กœ ์ ์–ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

Data fetching

Next JS๋ฅผ ์ด์šฉํ•œ Data fetching์—๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ ๊ณต์‹ ๋ฌธ์„œ๋ฅผ ์ฐธ์กฐํ•ด์ฃผ์„ธ์š”!

  • getStaticProps / getServerSideProps : Server Side์—์„œ ๋ฏธ๋ฆฌ page html์„ ๋งŒ๋“ค์–ด ๋‘ก๋‹ˆ๋‹ค.
  • Client Side : Client Side์—์„œ data๋ฅผ fetching ํ•ฉ๋‹ˆ๋‹ค.

Next JS์˜ ๊ณต์‹ ๋ฌธ์„œ์—์„œ๋Š” getStaticProps์—์„œ pre-render๊ฐ€ ํ•„์š”ํ•œ ์ปดํฌ๋„ŒํŠธ์˜ data๋ฅผ fetchingํ•˜๊ณ  Client Side์—์„œ๋Š” pre-render๊ฐ€ ํ•„์š”์—†๊ฑฐ๋‚˜ user์˜ interaction์— ๋”ฐ๋ผ ๋ณ€๊ฒฝ๋˜๋Š” data๋ฅผ fetchingํ•ฉ๋‹ˆ๋‹ค.

 

Client Side์˜ data fetching์€ ๋ฌผ๋ก  axios, fetch ๋“ฑ์˜ web api๋ฅผ ๋ฐ”๋กœ ์‚ฌ์šฉํ•ด๋„ ๋˜์ง€๋งŒ, react-query๋‚˜ SWR๊ณผ ๊ฐ™์ด ์บ์‹ฑ๊ณผ ํ•จ๊ป˜ ํšจ๊ณผ์ ์œผ๋กœ fetchingํ•ด์ฃผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค. Next JS์˜ ๊ณต์‹๋ฌธ์„œ์—์„œ๋„ SWR์„ ์ด์šฉํ•œ data fetching์„ practice code๋กœ ์“ฐ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

ํ•ด๋‹น ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค์€ ๊ณตํ†ต์ ์œผ๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ฝ”๋“œ ํ๋ฆ„์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค. useData๋กœ๋ถ€ํ„ฐ data๋ฅผ ๋ฐ›์•„์˜ค๊ธฐ ์ „๊นŒ์ง€๋Š” ๊ธฐ์กด ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋งํ•˜์ง€ ์•Š๊ณ  ๋Œ€์‹  loading๊ณผ ๊ฐ™์€ ๋Œ€์ฒด ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค.

const { data: nowDate, isLoading, isError } = useData();

if (isLoading) return <div>loading...</div>;
if (isError) return <div>error</div>;

return (
	<div id='anchoring-target'>{nowDate.date}</div> // (1)
);

 

Issue

์ƒํ™ฉ

์•ต์ปค๋ง์ด ํŽ˜์ด์ง€ ์ฒซ ์ ‘๊ทผ ์‹œ ๋™์ž‘ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ๋‹ค๋งŒ, ์ ‘๊ทผ ์ดํ›„ url ๋’ค์— hash(#)๋ฅผ ๋ถ™์ด๊ฑฐ๋‚˜ ์ฝ”๋“œ ์ƒ์˜ router.push ํ†ตํ•ด ์ด๋™ํ•˜๋ฉด ์ œ๋Œ€๋กœ ๋™์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค.

 

์ด์Šˆ ์ •๋ฆฌ

์œ„์˜ ์ฝ”๋“œ์™€ ๊ฐ™์ด ์ฝ”๋“œ๋ฅผ ๊ตฌ์„ฑํ•  ๊ฒฝ์šฐ useData๋ฅผ ํ†ตํ•œ data๋ฅผ fetchingํ•ด์˜ค๊ธฐ ์ „๊นŒ์ง€๋Š” ์ฝ”๋“œ (1)๋ฒˆ์˜ div๊ฐ€ ๋…ธ์ถœ ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

SSR์„ ์‚ฌ์šฉํ•˜๋Š” Next js ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์œ„์˜ ์ฝ”๋“œํ๋ฆ„์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  1. Server Side์—์„œ data fetching์ด ํ•„์š”์—†๋Š” ๋ถ€๋ถ„์„ pre-render ํ•˜๊ธฐ → ์ด ๋•Œ, data๊ฐ€ ์—†์œผ๋ฏ€๋กœ loading์ด ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.
  2. Client Side์—์„œ useData๊ฐ€ ์ž‘๋™ํ•˜์—ฌ data๋ฅผ ๋ฐ›์•„์˜ต๋‹ˆ๋‹ค.
  3. ๋ฐ›์•„์˜จ ๋ฐ์ดํ„ฐ๋กœ (1)๋ฒˆ์˜ div๊ฐ€ ๋ Œ๋”๋ง๋ฉ๋‹ˆ๋‹ค.

๋งŒ์•ฝ ์ตœ์ดˆ ์ ‘๊ทผํ•˜๋Š” url์— hash(#anchoring-target)์ด ๋ถ™์–ด ๊ณง๋ฐ”๋กœ ํ•ด๋‹น ์œ„์น˜๋กœ ์ด๋™ํ•ด์•ผ ํ–ˆ๋‹ค๋ฉด ์œ„์˜ ์ฝ”๋“œ๋Š” ์•ต์ปค๋ง์ด ๋™์ž‘ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์•ต์ปค๋ง ๋™์ž‘ ์ž์ฒด๋Š” Server Side์—์„œ ์ƒ์„ฑ๋œ page์—์„œ ๋™์ž‘ ์™„๋ฃŒ ํ–ˆ๋‹ค๊ณ  ์ทจ๊ธ‰๋˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋‹ค๋งŒ Server Side์—์„œ๋Š” useData๊ฐ€ ๋™์ž‘ํ•˜๊ธฐ ์ „์ด๋ฏ€๋กœ Loading๋งŒ์ด ํ‘œ์‹œ๋˜๊ณ  ์•ต์ปค๋ง์€ ์ œ๋Œ€๋กœ ๋™์ž‘ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

 

ํ•ด๊ฒฐ

ํ•ด๋‹น ์ด์Šˆ๋Š” ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์œผ๋กœ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  1. Server Side์—์„œ fetchingํ•œ data๋กœ default๋กœ ์ปดํฌ๋„ŒํŠธ ๊ตฌ์„ฑ ํ›„, Client Side์—์„œ fetchingํ•œ ๋ฐ์ดํ„ฐ๋กœ ๊ฐฑ์‹ ํ•˜๊ธฐ (default data๋ฅผ ๊ทธ๋ƒฅ ๋ฏธ๋ฆฌ ์ง€์ •ํ•ด๋‘๋Š” ๊ฒƒ๋„ ํ•œ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.)
  2. data๊ฐ€ ์—†๋Š” ์ƒํƒœ์˜ ๋ Œ๋”๋ง์„ ํ‹€์ด ์œ ์ง€๋˜๋„๋ก ํ•˜๊ธฐ (์ƒ๋‹จ ์ฝ”๋“œ์—์„œ div๋Š” ๋…ธ์ถœ๋˜๋„๋ก) 
const { data: nowDate } = useData();

return (
	<div id='anchoring-target'>{nowDate?.date}</div> // ? ์—ฐ์‚ฐ์ž๋กœ data๊ฐ€ ์—†์œผ๋ฉด ํ‘œ์‹œํ•˜์ง€ ์•Š๊ธฐ
);

 

๊ทผ๋ณธ์ ์ธ ํ•ด๊ฒฐ

๋ฌธ์ œ๋Š” ์ด๋ ‡๊ฒŒ ๋ฐœ์ƒํ•œ ์•ต์ปค๋ง ๋ฌธ์ œ๋ฅผ Client data fetching์ด ์›์ธ์ด๋ผ๊ณ  ์ฐพ์•„๋‚ด๊ธฐ ์–ด๋ ต๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ์•ž์œผ๋กœ ๋””๋ฒ„๊น… ์‹œ์—๋Š” SSR์„ ์ด์šฉํ•จ์— ๋”ฐ๋ผ ๋ฐœ์ƒํ•˜๋Š” ์ด์Šˆ์ธ ์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด Server Side์—์„œ ์ƒ์„ฑ๋˜๋Š” ํŽ˜์ด์ง€๋ฅผ ๋ณด๊ณ  ์–ด๋–ค ์ปดํฌ๋„ŒํŠธ๋“ค์ด ๋ฏธ๋ฆฌ ์ƒ์„ฑ๋˜์–ด ์žˆ๋Š” ์ง€๋ฅผ ํŒŒ์•…ํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค.

๋˜ํ•œ, ์• ์ดˆ์— ์ด๋Ÿฌํ•œ ๋ฌธ์ œ์˜ ๋ฐœ์ƒ์„ ๋ง‰๊ธฐ ์œ„ํ•ด ์ฝ”๋“œ ์Šคํƒ€์ผ์„ ๊ณ ์ •ํ•  ํ•„์š”๊ฐ€ ์žˆ๋Š”๋ฐ ์ œ๊ฐ€ ์ œ์•ˆํ•˜๋Š” ๋ฐฉ์‹์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • user์™€์˜ interaction์ด ์—†๋Š” ์ปดํฌ๋„ŒํŠธ๋Š” Server Side์—์„œ data fetchingํ•ด์˜ค๊ธฐ
  • Client side์—์„œ data fetching์„ ํ•ด์•ผ ํ•œ๋‹ค๋ฉด ํ”„๋ ˆ์ž„์„ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ๋„๋ก Server Side์—์„œ ์ ์šฉ๋  default data๋ฅผ ํ• ๋‹นํ•ด์ฃผ๊ธฐ

 

๋ฐ˜์‘ํ˜•