๐ฅน ํ ์ผ ๋ฆฌ์คํธ๋ฅผ ์ฐ๋ ๊ฒ โ ์ค์ ๋ก ๊ทธ ์ผ์ ํ๋ ๊ฒ
useQuery๋ React Query์ ํต์ฌ ํ ์ผ๋ก, ์๋ฒ์์ ๋ฐ์ดํฐ๋ฅผ ํ์นญํ๊ณ ์บ์ฑ, ์๋ฌ ์ฒ๋ฆฌ ๋ฐ ๋ก๋ฉ ์ํ๋ฅผ ๊ด๋ฆฌํฉ๋๋ค. ์ด ํ ์ ๋น๋๊ธฐ์ ์ผ๋ก ์๋ฒ์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ฉฐ, ์ปดํฌ๋ํธ์ ์๋ช ์ฃผ๊ธฐ์ ์ฐ๊ฒฐ๋์ด ๋ฐ์ดํฐ๋ฅผ ์๋์ผ๋ก ๋ฆฌํ์นญํ๊ฑฐ๋ ์บ์ฑ๋ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฌ์ฉํ ์ ์๊ฒ ํด์ค๋๋ค.
useQuery์ ์ฃผ์ ๋ฌธ๋ฒ๊ณผ ์ฌ์ฉ ๋ฐฉ์:
1. ๊ธฐ๋ณธ ์ฌ์ฉ๋ฒ: useQuery(queryKey, queryFn, options)
queryKey: ์ฟผ๋ฆฌ๋ฅผ ๊ณ ์ ํ๊ฒ ์๋ณํ๋ ํค์
๋๋ค. ์ฟผ๋ฆฌ ์บ์์์ ์ด ํค๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ๊ด๋ฆฌํ๊ณ ์๋ณํฉ๋๋ค.
queryFn: ๋ฐ์ดํฐ๋ฅผ ํ์นญํ๋ ํจ์์
๋๋ค. ์ด ํจ์๋ ์ฃผ๋ก ์๋ฒ๋ API๋ก๋ถํฐ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ๋น๋๊ธฐ ํจ์์
๋๋ค.
options: ์ฟผ๋ฆฌ ์คํ์ ์ ์ดํ๋ ๋ค์ํ ์ค์ ์ด ํฌํจ๋ฉ๋๋ค. (์: ๋ก๋ฉ ์ค์ธ ์ํ, ์๋ฌ ์ฒ๋ฆฌ, ์ฑ๊ณต ์ ์คํํ ์ฝ๋ฐฑ ๋ฑ)
2. data, error, isLoading
useQuery๋ ๋ค์๊ณผ ๊ฐ์ ์ํ ๊ฐ์ ๋ฐํํฉ๋๋ค:
data: ์ฟผ๋ฆฌ๊ฐ ์ฑ๊ณต์ ์ผ๋ก ์คํ๋์์ ๋ ๊ฐ์ ธ์จ ๋ฐ์ดํฐ๋ฅผ ๋ฐํํฉ๋๋ค.
error: ์ฟผ๋ฆฌ๊ฐ ์คํจํ์ ๋ ๋ฐ์ํ ์๋ฌ ๊ฐ์ฒด๋ฅผ ๋ฐํํฉ๋๋ค.
isLoading: ๋ฐ์ดํฐ๊ฐ ๋ก๋ฉ ์ค์ผ ๋ true๋ฅผ ๋ฐํํ๊ณ , ๋ฐ์ดํฐ ๋ก๋๊ฐ ์๋ฃ๋๋ฉด false๊ฐ ๋ฉ๋๋ค.
์์๋ฅผ ๋ฐํ์ผ๋ก ์ค๋ช
:
์ ์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ์ปค์คํ
ํ
(useUserData) ์์:
const {
data: user, // ์๋ฒ์์ ๊ฐ์ ธ์จ ์ ์ ๋ฐ์ดํฐ๋ฅผ user ๋ณ์์ ์ ์ฅ
error: userError, // ์ ์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ์ค ์๋ฌ๊ฐ ๋ฐ์ํ์ ๋์ ์๋ฌ ๋ฉ์์ง
isLoading: userLoading // ๋ฐ์ดํฐ๊ฐ ๋ก๋ฉ ์ค์ผ ๋ true, ๋ก๋ฉ ์๋ฃ ์ false
} = useQuery('user', fetchUserAuth, { // 'user'๋ผ๋ ํค๋ก ์ฟผ๋ฆฌ๋ฅผ ๊ด๋ฆฌํ๋ฉฐ, fetchUserAuth ํจ์๋ฅผ ํตํด ๋ฐ์ดํฐ๋ฅผ ํ์น
onSuccess: (user) => {
if (user) {
setUserId(user.id); // ์ฟผ๋ฆฌ ์ฑ๊ณต ์ ์ ์ญ ์ํ๋ก userId๋ฅผ ์ ์ฅ
setEmail(user.email ?? null); // ์ฟผ๋ฆฌ ์ฑ๊ณต ์ ์ด๋ฉ์ผ ์ ์ฅ
}
}
});
์ค๋ช
:
'user': ์ฟผ๋ฆฌ์ ๊ณ ์ ํค์
๋๋ค. useQuery๋ ์ด ํค๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์บ์๋ ๋ฐ์ดํฐ๋ฅผ ์๋ณํฉ๋๋ค. ๋ง์ฝ 'user'๋ผ๋ ํค๋ก ๋ค๋ฅธ ๊ณณ์์ ์ฟผ๋ฆฌ๋ฅผ ์คํํ๋ฉด ์บ์ฑ๋ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ๊ฑฐ๋, ํ์ํ ๊ฒฝ์ฐ ์๋ฒ์ ๋ค์ ์์ฒญํฉ๋๋ค.
fetchUserAuth: ์ ์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ๋น๋๊ธฐ ํจ์์ ๋๋ค. supabase.auth.getUser๋ฅผ ํธ์ถํ์ฌ ์ธ์ฆ๋ ์ ์ ๋ฐ์ดํฐ๋ฅผ ์๋ฒ์์ ๊ฐ์ ธ์ต๋๋ค.
onSuccess ์ต์ :
์ฑ๊ณต ์ ํธ์ถ๋๋ ์ฝ๋ฐฑ ํจ์์
๋๋ค. ์ฟผ๋ฆฌ๊ฐ ์ฑ๊ณต์ ์ผ๋ก ์๋ฃ๋ ํ, ๋ฐ์ดํฐ๋ฅผ ์ด์ฉํด setUserId์ setEmail์ ํธ์ถํ์ฌ ์ ์ ์ ID์ ์ด๋ฉ์ผ์ ์ ์ญ ์ํ(Zustand)์ ์ ์ฅํฉ๋๋ค.
๋๋ค์์ ๊ฐ์ ธ์ค๋ ์ปค์คํ
ํ
(useUserNickname) ์์:
const {
data: nickname, // ํ์นญ๋ ๋๋ค์
error: nicknameError, // ์๋ฌ๊ฐ ๋ฐ์ํ์ ๋์ ์๋ฌ ๋ฉ์์ง
isLoading: nicknameLoading // ๋๋ค์ ๋ฐ์ดํฐ๋ฅผ ๋ก๋ฉ ์ค์ผ ๋ true, ๋ก๋ฉ ์๋ฃ ์ false
} = useQuery(['nickname', userId], fetchNickname, {
enabled: !!userId, // userId๊ฐ ์กด์ฌํ ๋๋ง ์ฟผ๋ฆฌ๋ฅผ ์คํ
onSuccess: (nickname) => {
setNickname(nickname ?? ''); // ์ฟผ๋ฆฌ๊ฐ ์ฑ๊ณตํ์ ๋ ๋๋ค์์ ์ ์ญ ์ํ์ ์ ์ฅ
}
});
์ค๋ช
:
['nickname', userId]: ์ฟผ๋ฆฌ ํค๋ก ๋ฐฐ์ด์ ์ฌ์ฉํ๊ณ ์์ต๋๋ค. ์ด ๋ฐฐ์ด์ ์ ์ ์ userId์ ์ฐ๊ฒฐ๋ ๋๋ค์ ๋ฐ์ดํฐ๋ฅผ ์บ์ฑํ๊ธฐ ์ํ ๊ณ ์ ์๋ณ์ ์ญํ ์ ํฉ๋๋ค.
์๋ฅผ ๋ค์ด, ๋์ผํ ํค๋ฅผ ์ฌ์ฉํด ๋๋ค์์ ์์ฒญํ๋ฉด, ์ด๋ฏธ ํ์นญ๋ ๋ฐ์ดํฐ๊ฐ ์บ์์์ ๋ฐํ๋ ์ ์์ต๋๋ค.
fetchNickname: ๋๋ค์์ ํ์นญํ๋ ๋น๋๊ธฐ ํจ์์
๋๋ค. Supabase์ users ํ
์ด๋ธ์์ nickname ํ๋๋ฅผ ๊ฐ์ ธ์ต๋๋ค.
enabled ์ต์ :
!!userId: userId๊ฐ ์กด์ฌํ ๋๋ง ์ฟผ๋ฆฌ๋ฅผ ์คํํ๋๋ก ํฉ๋๋ค. ์ฆ, userId๊ฐ null ๋๋ undefined์ผ ๋ ์ฟผ๋ฆฌ๊ฐ ์คํ๋์ง ์๋๋ก ์ ์ดํฉ๋๋ค.
onSuccess ์ต์
:
์ฟผ๋ฆฌ๊ฐ ์ฑ๊ณต์ ์ผ๋ก ์๋ฃ๋๋ฉด setNickname์ ํตํด ๋๋ค์์ ์ ์ญ ์ํ(Zustand)์ ์ ์ฅํฉ๋๋ค.
๋ ๋ฒจ ์ด๋ฆ์ ๊ฐ์ ธ์ค๋ ์ปค์คํ
ํ
(useUserLevel) ์์:
const {
data: levelName,
error: levelNameError,
isLoading: levelLoading
} = useQuery(['levelName', userId], fetchLevelName, {
enabled: !!userId, // userId๊ฐ ์์ ๋๋ง ์ฟผ๋ฆฌ๋ฅผ ์คํ
onSuccess: (levelName) => {
setLevelName(levelName ?? ''); // ์ฑ๊ณต ์ ๋ ๋ฒจ ์ด๋ฆ์ ์ ์ญ ์ํ์ ์ ์ฅ
}
});
์ค๋ช
:
['levelName', userId]: ์ฟผ๋ฆฌ ํค๋ก userId์ ์ฐ๊ฒฐ๋ ๋ ๋ฒจ ์ด๋ฆ์ ์บ์ฑํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.
์ฌ๋ฌ ์ฌ์ฉ์์ ๋ ๋ฒจ ๋ฐ์ดํฐ๋ฅผ ๊ด๋ฆฌํ ์ ์์ต๋๋ค. ๊ฐ๊ฐ์ userId์ ๋ํ ์บ์๊ฐ ๋ฐ๋ก ๊ด๋ฆฌ๋ฉ๋๋ค.
fetchLevelName: ์ ์ ์ ๋ ๋ฒจ ์ด๋ฆ์ ๊ฐ์ ธ์ค๋ ๋น๋๊ธฐ ํจ์์
๋๋ค.
users ํ
์ด๋ธ์์ level_id๋ฅผ ๊ฐ์ ธ์ค๊ณ , ์ด๋ฅผ ๊ธฐ๋ฐ์ผ๋ก level ํ
์ด๋ธ์์ ๋ ๋ฒจ ์ด๋ฆ์ ์กฐํํฉ๋๋ค.
enabled:
userId๊ฐ ์์ ๋๋ง ์ฟผ๋ฆฌ๋ฅผ ์คํํ๋๋ก ์ ์ดํฉ๋๋ค. ์ด๋ฅผ ํตํด ๋ถํ์ํ ์ฟผ๋ฆฌ ์คํ์ ๋ฐฉ์งํฉ๋๋ค.
์ถ์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ์ปค์คํ
ํ
(useUserAttendance) ์์:
const {
data: attendance,
error: attendanceError,
isLoading: attendanceLoading
} = useQuery(['attendance', userId], fetchAttendance, {
enabled: !!userId, // userId๊ฐ ์์ ๋๋ง ์ฟผ๋ฆฌ ์คํ
onSuccess: (attendance) => {
setAttendance(attendance ?? 0); // ์ฑ๊ณต ์ ์ถ์ ๋ฐ์ดํฐ๋ฅผ ์ ์ญ ์ํ์ ์ ์ฅ
}
});
์ค๋ช
:
['attendance', userId]: ์ฟผ๋ฆฌ ํค๋ก ์ ์ ์ ์ถ์ ๋ฐ์ดํฐ๋ฅผ ์บ์ฑํ๊ณ ๊ด๋ฆฌํฉ๋๋ค. userId๊ฐ ๋ค๋ฅด๋ฉด ๊ฐ๊ฐ์ ์บ์๊ฐ ๋ณ๋๋ก ๊ด๋ฆฌ๋ฉ๋๋ค.
fetchAttendance: users ํ ์ด๋ธ์์ attendance ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ๋น๋๊ธฐ ํจ์์ ๋๋ค.
enabled:
userId๊ฐ ์๋ ๊ฒฝ์ฐ์๋ง ์ฟผ๋ฆฌ๋ฅผ ์คํํ๋๋ก ์ ์ดํ์ฌ ํจ์จ์ ์ธ ์ฟผ๋ฆฌ ์คํ์ ๋ณด์ฅํฉ๋๋ค.
onSuccess:
์ถ์ ๋ฐ์ดํฐ๋ฅผ ์ฑ๊ณต์ ์ผ๋ก ๊ฐ์ ธ์์ ๋ ์ ์ญ ์ํ์ ์ถ์ ํ์๋ฅผ ์ ์ฅํฉ๋๋ค.
๊ฒฐ๋ก :
useQuery๋ ์๋ฒ์์ ๋ฐ์ดํฐ๋ฅผ ๋น๋๊ธฐ์ ์ผ๋ก ๊ฐ์ ธ์ค๊ณ , ์บ์ฑ, ๋ก๋ฉ ๋ฐ ์๋ฌ ์ํ ๊ด๋ฆฌ, ์ฑ๊ณต ์ ํ์ฒ๋ฆฌ๋ฅผ ํ ์ ์๋ ๋งค์ฐ ๊ฐ๋ ฅํ ๋๊ตฌ์
๋๋ค. ์ ์ฝ๋์์ useQuery๋ ๊ฐ์ข
์ ์ ๋ฐ์ดํฐ(๋๋ค์, ๋ ๋ฒจ, ์ถ์ ํ์ ๋ฑ)๋ฅผ ๊ฐ์ ธ์ ์บ์ฑํ๊ณ , zustand๋ฅผ ํตํด ์ ์ญ ์ํ์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๋ ํ๋ฆ์ ๊ฐ๊ฒฐํ๊ฒ ์ฒ๋ฆฌํฉ๋๋ค.
์๋ ๊ทผ๋ฐ ์ ์ฝ๋ ์๋ฌ๋๋ค๊ณ ์ใ
ใ
ใ
ใ
ใ
ใ
1. zustand ์ฌ์ฉ โก๏ธ useQuery๋ก ์์ ํ์
2. ์ธ์๋ฅผ 3๊ฐ ๋ฐ๊ณ ์๋ค, overload ๋งค์นญ์ด ์ ๋๋ค โก๏ธ useQuery()์ ์ธ์๊ฐ ๊ฐ์ฒด ํํ์ธ ๋ถ๋ถ์ ์ธ์ํ๋ ๋ฐ์ ์๊ธด ๋ฌธ์ ์ด๋ฏ๋ก
queryKey, queryFn์ ๋ช
์์ ์ผ๋ก ์จ์ ์์ ํ์