λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°

Web Development/JAVASCRIPT

μƒνƒœκ΄€λ¦¬ [4편]: Tanstack-Query, μ™œ ν”„λ‘ νŠΈμ—”λ“œμ—μ„œ μƒνƒœλ₯Ό λ‚˜λˆ  관리해야 ν• κΉŒ?

πŸ€” μ™œ μƒνƒœ 관리가 μ΄λ ‡κ²Œ λ³΅μž‘ν• κΉŒ?

ν”„λ‘ νŠΈμ—”λ“œ κ°œλ°œμ„ ν•˜λ‹€ 보면 “이 μƒνƒœλŠ” 어디에 μ €μž₯ν•΄μ•Ό ν•˜μ§€?” ν•˜λŠ” 고민이 μƒκΉλ‹ˆλ‹€.
둜그인 정보, λͺ¨λ‹¬ μ—΄λ¦Ό μ—¬λΆ€, API μ‘λ‹΅κ°’κΉŒμ§€…
이 λͺ¨λ“  κ±Έ ν•˜λ‚˜μ˜ μƒνƒœλ‘œ 묢어도 λ κΉŒμš”?

 

1. APIμ—μ„œ λ°›μ•„μ˜¨ 정보가 κ³§ ν΄λΌμ΄μ–ΈνŠΈ μƒνƒœ μ•„λ‹Œκ°€?

μ²˜μŒμ—” μ΄λ ‡κ²Œ 생각할 수 μžˆμ–΄μš”. “μ„œλ²„μ—μ„œ 데이터λ₯Ό λ°›μ•„μ˜€λ©΄ 그게 λ°”λ‘œ μƒνƒœμ§€!”
ν•˜μ§€λ§Œ μ‹€μ œλ‘œλŠ” 두 κ°€μ§€ μƒνƒœλ‘œ λ‚˜λˆ μ„œ κ΄€λ¦¬ν•˜λŠ” 게 더 λͺ…ν™•ν•©λ‹ˆλ‹€.

ꡬ뢄 μ„œλ²„ μƒνƒœ (Server State) ν΄λΌμ΄μ–ΈνŠΈ μƒνƒœ (Client State)
μ •μ˜ μ„œλ²„μ—μ„œ κ°€μ Έμ˜¨ 데이터 λΈŒλΌμš°μ € λ‚΄λΆ€ UI μƒνƒœ
μ†Œμœ μž μ„œλ²„κ°€ 원본 (Source of Truth) ν”„λ‘ νŠΈμ—”λ“œ μ•±
μ˜ˆμ‹œ κ²Œμ‹œλ¬Ό λͺ©λ‘, μœ μ € 정보 λͺ¨λ‹¬ μ—΄λ¦Ό μ—¬λΆ€, ν˜„μž¬ νŽ˜μ΄μ§€, μž…λ ₯κ°’
동기화 ν•„μš” 예 (μ„œλ²„μ™€ μΌμΉ˜ν•΄μ•Ό 함) μ•„λ‹ˆμ˜€ (μ•±μ—μ„œλ§Œ μ‚¬μš©)

 

2. μ™œ ꡳ이 μ΄λ ‡κ²Œ λ‚˜λˆ μ•Ό ν• κΉŒ?

  • μ„œλ²„ μƒνƒœλŠ” 비동기이고 예츑이 어렀움
  • ν΄λΌμ΄μ–ΈνŠΈ μƒνƒœλŠ” λ‚΄κ°€ 직접 μ œμ–΄ κ°€λŠ₯
  • 동기화 μ±…μž„μ΄ 닀름 (API μš”μ²­ vs UI 이벀트)
  • ν…ŒμŠ€νŠΈμ™€ μœ μ§€λ³΄μˆ˜κ°€ μ‰¬μ›Œμ§

// κ΅¬λΆ„ν•΄μ„œ κ΄€λ¦¬ν•˜λ©΄ 깔끔함
const { data: user } = useQuery(['user'], fetchUser); // μ„œλ²„ μƒνƒœ
const [isEditing, setIsEditing] = useState(false);    // ν΄λΌμ΄μ–ΈνŠΈ μƒνƒœ

 

3. 맀번 API둜 κ°€μ Έμ˜€λ©΄ μ•ˆ λ˜λ‚˜?

λ‹¨μˆœνžˆ μƒκ°ν•˜λ©΄, νŽ˜μ΄μ§€λ§ˆλ‹€ μ„œλ²„μ—μ„œ μš”μ²­ν•˜λ©΄ λ˜λŠ” κ±° μ•„λ‹Œκ°€? μ‹Άμ§€λ§Œ, λ¬Έμ œκ°€ λ§ŽμŠ΅λ‹ˆλ‹€.

문제 μ„€λͺ…
속도 μ €ν•˜ 항상 μƒˆ μš”μ²­ = 느린 UX
μ„œλ²„ λΆ€ν•˜ 같은 데이터 반볡 μš”μ²­ → νŠΈλž˜ν”½ 증가
λΆˆν•„μš”ν•œ μš”μ²­ νŽ˜μ΄μ§€λ₯Ό μ™”λ‹€ κ°”λ‹€ ν•  λ•Œλ§ˆλ‹€ μƒˆλ‘œ μš”μ²­
μ˜€ν”„λΌμΈ 미지원 λ„€νŠΈμ›Œν¬ μˆœκ°„ 였λ₯˜ μ‹œ 아무것도 λͺ» λ³΄μ—¬μ€Œ

 

4. μ„œλ²„μ—μ„œ μΊμ‹±ν•˜λ©΄ λ˜μ§€ μ•Šλ‚˜?

λ¬Όλ‘  μ„œλ²„λ„ 캐싱을 ν•©λ‹ˆλ‹€. CDN, Redis 등을 톡해 λΉ λ₯΄κ²Œ μ‘λ‹΅ν•˜μ£ .
ν•˜μ§€λ§Œ ν”„λ‘ νŠΈμ—”λ“œμ— ν•„μš”ν•œ 캐싱은 쑰금 λ‹€λ¦…λ‹ˆλ‹€.

  • μ„œλ²„ μΊμ‹œλŠ” λͺ¨λ“  μ‚¬μš©μž 곡톡 – μ‚¬μš©μž 맞좀 데이터엔 ν•œκ³„ 있음
  • μ‚¬μš©μž λΈŒλΌμš°μ €μ— μ €μž₯ν•΄μ•Ό μ˜€ν”„λΌμΈ λŒ€μ‘ κ°€λŠ₯
  • UI νŒ¨ν„΄μ— 따라 μœ μ—°ν•˜κ²Œ 리패치 μ œμ–΄ν•΄μ•Ό 함

즉, ν”„λ‘ νŠΈμ—”λ“œλŠ” μ‚¬μš©μž κ²½ν—˜ μ΅œμ ν™”λ₯Ό μœ„ν•΄ 자체 캐싱 μ „λž΅μ΄ ν•„μš”ν•©λ‹ˆλ‹€.

 

5. κ·Έλž˜μ„œ λ‚˜μ˜¨ 도ꡬ - Tanstack Query

이런 문제λ₯Ό ν•΄κ²°ν•˜κΈ° μœ„ν•΄ μ‚¬μš©ν•˜λŠ” λŒ€ν‘œμ μΈ 도ꡬ가 Tanstack Queryμž…λ‹ˆλ‹€.

  • μžλ™ 캐싱
  • stale-while-revalidate νŒ¨ν„΄ 지원
  • μ—λŸ¬, λ‘œλ”© μƒνƒœ μžλ™ 관리

const { data: user } = useQuery(['user'], fetchUser);

Tanstack Query의 캐싱 κΈ°μ€€

μ˜΅μ…˜ μ„€λͺ…
Query Key μΊμ‹œλ₯Ό μ‹λ³„ν•˜λŠ” 고유 이름
staleTime 데이터λ₯Ό “μ‹ μ„ ”ν•˜λ‹€κ³  κ°„μ£Όν•  μ‹œκ°„
cacheTime μ–Έλ§ˆμš΄νŠΈ ν›„ μΊμ‹œ μœ μ§€ μ‹œκ°„
refetchOnWindowFocus μ°½ λ‹€μ‹œ μ—΄ λ•Œ μžλ™ 리패치
enabled μ‘°κ±΄λΆ€λ‘œ 쿼리 μ‹€ν–‰ μ œμ–΄

 

6. Tanstack QueryλŠ” 어디에 데이터λ₯Ό μ €μž₯ν• κΉŒ?

λͺ¨λ“  λ°μ΄ν„°λŠ” QueryClientλΌλŠ” 객체 μ•ˆμ— μ €μž₯λ©λ‹ˆλ‹€.


const queryClient = new QueryClient();


  

각 μ‚¬μš©μžμ˜ λΈŒλΌμš°μ € λ©”λͺ¨λ¦¬μ— μΊμ‹œκ°€ μ €μž₯되며, 같은 쿼리 ν‚€κ°€ λ“€μ–΄μ˜€λ©΄ κΈ°μ‘΄ 데이터λ₯Ό μž¬μ‚¬μš©ν•©λ‹ˆλ‹€.

 

βœ… μš”μ•½

  • API둜 λ°›μ•„μ˜¨ 데이터와 UI μƒνƒœλŠ” 성격이 λ‹€λ₯΄λ‹€ → 뢄리 ν•„μš”
  • 맀번 API μš”μ²­ν•˜λ©΄ UX, μ„±λŠ₯, μ„œλ²„ λΆ€ν•˜ μΈ‘λ©΄μ—μ„œ λΉ„νš¨μœ¨
  • μ„œλ²„ μΊμ‹œλ‘œλŠ” μ‚¬μš©μž κ°œμΈν™” λŒ€μ‘μ΄ 어렀움
  • ν”„λ‘ νŠΈμ—”λ“œ 캐싱은 μ‚¬μš©μž κ²½ν—˜ ν–₯상, μ˜€ν”„λΌμΈ λŒ€μ‘ 등에 ν•„μˆ˜
  • 이λ₯Ό μœ„ν•΄ Tanstack Query 같은 도ꡬλ₯Ό ν™œμš©ν•˜μž!