๐ป
์์ฆ ํ๋ก ํธ์๋ ํ๋ก์ ํธ์์ Zustand + TanStack Query๊ฐ ์์ฐ์ค๋ฝ๊ฒ ๊ฐ์ด ๋ฑ์ฅํ๋ค.
์ฒ์์๋ ๋ ๋ค ์ํ ๊ด๋ฆฌ์ฒ๋ผ ๋ณด์ฌ์ ์ด๊ฑฐ ๋ ์ค ํ๋๋ง ์ฐ๋ฉด ๋๋ ๊ฑฐ ์๋๊ฐ? ์ถ์๋๋ฐ ์ญํ ์ด ์์ ํ ๋ค๋ฅด๋ค.
์ด๋ฒ ๊ธ์์๋ ์ค์ ๋ก๊ทธ์ธ ํ๋ก์ฐ๋ฅผ ๊ตฌํํ๋ฉด์ ๋๋ ์ฐจ์ด๋ฅผ ์ ๋ฆฌํด๋ณธ๋ค.
1. Zustand๋ ๋ฌด์์ธ๊ฐ?
Zustand๋ ์ ์ญ ์ํ ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค.
Redux๋ณด๋ค ํจ์ฌ ๊ฐ๋จํ๊ณ , ๋ณด์ผ๋ฌํ๋ ์ดํธ๋ ๊ฑฐ์ ์๋ค.
ํ๋ก ํธ ๋ด๋ถ ์ํ๋ฅผ ์ ์ฅํ๋ ๊ณณ์ผ๋ก,
์๋ฅผ ๋ค๋ฉด ๋ก๊ทธ์ธ ๋ชจ๋ฌ ์ด๋ฆผ ์ฌ๋ถ, ๋คํฌ๋ชจ๋ ์ํ, ์ฌ์ด๋๋ฐ ์ด๋ฆผ/๋ซํ, ์ฌ์ฉ์๊ฐ ์ ํํ ํญ
์ด๋ฐ ๊ฒ๋ค์ ์ ์ฅํ๋ค.
์ฌ์ฉ์
import { create } from 'zustand'
export const useStore = create((set) => ({
isOpen: false,
toggle: () => set((state) => ({ isOpen: !state.isOpen })),
}))
2. TanStack Query๋ ๋ฌด์์ธ๊ฐ?
TanStack Query ์๋ฒ ๋ฐ์ดํฐ ๊ด๋ฆฌ ์์ง์ด๋ค.
์ฆ, API ํธ์ถ์ ์ค์ฌ์ผ๋ก ๋์๊ฐ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค.
๋จ์ํ fetch๋ง ํ๋ ๊ฒ ์๋๋ผ
์บ์ฑ, ์๋ ์ฌ์์ฒญ, ๋ก๋ฉ ์ํ ๊ด๋ฆฌ, ์๋ฌ ์ฒ๋ฆฌ, ๋ฐ์ดํฐ ๋๊ธฐํ ๋ฑ
์ด๋ฐ๊ฑธ ์ ๋ถ ์์์ ํด์ค๋ค.
์๋ฅผ ๋ค์ด ๋ก๊ทธ์ธ ์ํ๋ฅผ ํ์ธํ๋ API๊ฐ ์๋ค๊ณ ํด๋ณด์.
import { useQuery } from '@tanstack/react-query'
import axios from 'axios'
export const useAuthQuery = () => {
return useQuery({
queryKey: ['auth'],
queryFn: async () => {
const res = await axios.get('/api/auth/me', {
withCredentials: true,
})
return res.data
},
retry: false,
})
}
์ด ํ ์ค๋ก “๋ก๊ทธ์ธ ์ํ + ์บ์ฑ + ๋ก๋ฉ + ์๋ฌ ์ฒ๋ฆฌ”๊ฐ ๋ค ํด๊ฒฐ๋๋ค.
3. ๋์ ์ฐจ์ด ํ ๋ฒ์ ์ ๋ฆฌ
| ๊ตฌ๋ถ | Zustand | TanStack Query |
| ์ญํ | ํด๋ผ์ด์ธํธ ์ํ | ์๋ฒ ์ํ |
| ๋ฐ์ดํฐ ์์น | ๋ธ๋ผ์ฐ์ | ์๋ฒ |
| ์ฃผ์ ๊ธฐ๋ฅ | ์ํ ์ ์ฅ | API ๊ด๋ฆฌ |
| ๋ก๋ฉ/์๋ฌ | ์ง์ ๊ตฌํ | ์๋ ์ ๊ณต |
ํต์ฌ์ “๋ฐ์ดํฐ๊ฐ ์ด๋์์ ์๋๋”
๐ก ์๋ฒ์์ ์๋ค → TanStack Query
๐ข ํ๋ก ํธ์์ ๋ง๋ ์ํ๋ค → Zustand
4. ๋ก๊ทธ์ธ ๊ตฌํ์์์ ์ค์ ์ฐจ์ด
์นด์นด์ค ๋ก๊ทธ์ธ ๊ธฐ๋ฐ์ผ๋ก ๊ตฌํํ๋ฉด์ ์ด ์ฐจ์ด๊ฐ ๋ ๋ช ํํด์ก๋ค.
1. ๋ก๊ทธ์ธ ์ฑ๊ณต → accessToken, refreshToken ์ฟ ํค ์ ์ฅ
2. ํ๋ก ํธ๋ ํ ํฐ์ ์ฝ์ ์ ์์ (httpOnly ์ฟ ํค)
3. API๋ก ๋ก๊ทธ์ธ ์ฌ๋ถ ํ์ธ
์ฌ๊ธฐ์ ์ค์ํ ํฌ์ธํธ, ๋ก๊ทธ์ธ ์ฌ๋ถ๋ ์๋ฒ์ ๋ฌผ์ด๋ด์ผ ํ๋ค๋ ๊ฒ
์ฆ, ์ด๊ฑด Zustand๊ฐ ์๋๋ผ TanStack Query ์์ญ์ด๋ค.
๐ ์ฌ๋ฐ๋ฅธ ๊ตฌ์กฐ
์ฒ์์ Zustand์ ์ ์ ์ํ๋ฅผ ์ ์ฅํ๋ ค๊ณ ํ๋ค.
๊ทธ๋ ๊ฒ ํ๋ฉด ๋ฌธ์ ๋ ํ์ด์ง ์ด๋๋ง๋ค API๋ฅผ ํธ์ถ ํด์ผํ๊ณ , ๋๊ธฐํ๊ฐ ๊นจ์ง๋ฉฐ ์ํ๊ฐ ๊ผฌ์ธ๋ค.
๊ทธ๋์ TanStack Query์๋ ์๋ฒ ์ํ๋ฅผ ์ ์ฅํ๊ณ , Zustand์๋ UI ์ํ๋ฅผ ์ ์ฅํ๋ ๊ตฌ์กฐ๋ก ๋ฐ๊พธ๋ ๊ฒ ๋ง๋ค!
1. TanStack Query → ์๋ฒ ์ํ
const { data, isLoading, isError } = useAuthQuery()
๐ก ๋ก๊ทธ์ธ ์ฌ๋ถ ํ๋จ
๐ก ์ ์ ์ ๋ณด ๊ฐ์ ธ์ค๊ธฐ
๐ก ์๋ ์บ์ฑ
2. Zustand → UI ์ํ
isLoginModalOpen: false
toggleLoginModal: () => {}
๐ข ๋ชจ๋ฌ ์ด๋ฆผ ์ฌ๋ถ
๐ข UI ์ํ ๊ด๋ฆฌ
5. ์ค์ ํ๋ฆ
์ต์ข ์ ์ธ ๋ก๊ทธ์ธ ํ๋ฆ:
๋ธ๋ผ์ฐ์ ์ ์ (/)
→ ๋ก๊ทธ์ธ ๊ฒ์ฆ API ์์ฒญ
→ ์๋ฒ๊ฐ ๋ก๊ทธ์ธ ์ฌ๋ถ ํ๋จ
→ TanStack Query๊ฐ ๊ฒฐ๊ณผ ๊ด๋ฆฌ
→ ๋ผ์ฐํ ๋ถ๊ธฐ (/home ๋๋ /login)
์ฌ๊ธฐ์ Zustand๋ ๋ฑ์ฅํ์ง ์๋๋ค.
๊ฒฐ๋ก
์ฒ์์ ๋ ๋ค ์ํ ๊ด๋ฆฌ์ฒ๋ผ ๋ณด์ฌ์ ํท๊ฐ๋ฆฌ์ง๋ง
์ค์ ๋ก ์จ๋ณด๋ฉด ์์ ํ ๋ค๋ฅธ ๋๊ตฌ๋ผ๋ ๊ฑธ ์๊ฒ ๋๋ค.
์๋ฒ ๋ฐ์ดํฐ๋ TanStack Query๋ก ๊ด๋ฆฌ
UI ์ํ๋ Zustand๋ก ๊ด๋ฆฌ
์ด ๊ตฌ์กฐ๋ก ๊ฐ๋ฉด ์ฝ๋๊ฐ ํจ์ฌ ๋จ์ํด์ง๊ณ ,
ํนํ ๋ก๊ทธ์ธ ๊ฐ์ ์ธ์ฆ ๋ก์ง์ด ์์ ์ ์ผ๋ก ๋์๊ฐ๋ค.

๋๊ธ