react-query๋ฅผ ์งง๊ฒ ์ฌ์ฉํด๋ณธ ํ๊ณ ..๋๊น...?
์ง๊ธ ์งํํ๊ณ ์๋ ํ๋ก์ ํธ์์ react-query์ recoil์ ์ฌ์ฉํด์ ์ํ๊ด๋ฆฌ๋ฅผ ํด์ฃผ๊ณ ์๋ค.
๋ฌผ๋ก ํ๋ก์ ํธ๊ฐ ์์ง ๋๋์ง ์์๋คใ ใ ..
์ฌ์ค ์๋ ๊น์ง๋ง ํด๋ ์ฑ์ฉ๊ณต๊ณ ๋ ๊ทธ๋ฐ ๊ณณ๋ค์ Redux๊ฐ ๊ฐ๋์ฐผ์๋๋ฐ ์ด๋ ์๊ฐ๋ถํด๊ฐ React-Query์ ์ ์ ์จ์ด ๋์์ง๊ธฐ ์์ํ๋ค.
๊ณต๋ถํด์ผ์ง..ํด์ผ์ง..์๊ฐํ๋ค๊ฐ ์ฌ์ฉํ๊ณ ์๋ ํ๋ก์ ํธ์ ์ฐ์ฐํ ๋ค์ด๊ฐ๊ฒ ๋๋ฉด์ ํด์ผ๋งํ๊ฒ ๋๋ค..
๋ฆฌ์ฝ์ผ์ ์ด์ ์ ํ์ตํด๋ดค๋๋ฐ ๋ฆฌ์กํธ ์ฟผ๋ฆฌ๋ ์ํด๋ด์ ์ด์ง ๊ฒ์ด ๋ฌ์๋ค
๊ทผ๋ฐ ์ง๊ธ ํด๋ณด๋ ์ ์ฉํ๊ณ ์ฌ์ฉํ๋ ๋ฐ์ ์์ด์๋ ํฌ๊ฒ ์ด๋ ต์ง ์์ผ๋ ๋์ฒ๋ผ ๊ฒ๋จน์ ์ฌ๋์ด ์๋ค๋ฉด ์ผ๋จ ํด๋ณด๋ผ๊ณ ๋งํ๊ณ ์ถ๋ค.
์ผ๋จ ๋๋์ฒด ์์ฆ ์ ๋ค ๋ฆฌ์กํธ ์ฟผ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ ๊ฑด์ง์ ๋ํ ์๋ฌธ์ด ๋ค์์๋ค.
์ดํดํด๋ณด๋ ค๊ณ ์๋ฃ๋ฅผ ๋ง์ด ์ฐพ์๋ดค๋๋ฐ ์๋ฃ๋ ์๋ฃ์ง๋ง ์ง์ ํด๋ณด๊ณ ๊นจ๋ซ๋๊ฒ ์ ์ผ ์ดํด๊ฐ ์ ๋์๋ค.
๊ทธ๋์ ์๋ฃ๋ ๋์ ์ ํด์ ๊ธฐ์กด์ ์ํ๊ด๋ฆฌ๋ฅผ ๋ฆฌ์กํธ ์ฟผ๋ฆฌ๋ก ๋ฐ๊ฟ๋ณธ ๊ทธ๋ฐ ๊ธ๋ค์ ๋ง์ด ๋ดค๋ค.
๊ทธ๋์ ์งง์ง๋ง ๋ ๋ฌ๊ฐ๋ ์ฌ์ฉํด๋ณธ ์ฐ๋ญ์ด์ธ ๋ด๊ฐ ์ด๋ค ์ ์ ๋๋ ์ ์์๋์ง์ ๋ํด ์ ์ด๋ณด๋ ค๊ณ ํ๋ค.
์ง์งํ ๊ธ์ ์๋๋ค...๊ทธ๋ฅ ๋ด๊ฐ ํด๋ณธ ์์ ๊น์ด์์ ๋๋ ๊ธ์ผ๋ฟ..
์ ์ฉํ ์ด์
์ ์ฌ์ง์ ๊ณต์๋ฌธ์๋ก ๊ฐ๋ฉด ์ด๋ฐ ํ๋ฉด์ ๋ณผ ์ ์์๊ฒ์ด๋ค.
๋ด ๋์ ์ ์ผ ๋ณด์ธ ๊ฒ์ ASYNCHRONOUS STATE MANAGEMENT์๋ค. ๋ฐ๋ก '๋น๋๊ธฐ ์ํ๊ด๋ฆฌ'๋ผ๋ ๊ฑฐ๋ค.
wow ์ค๋๋ ๋์ค๋ ๋น๋๊ธฐ
๊ณต์๋ฌธ์์ ๋ฐ๋ฅด๋ฉด ๋ฆฌ์กํธ ์ฟผ๋ฆฌ๋ React์์ ์๋ฒ์ํ๋ฅผ ๊ฐ์ ธ์ค๊ณ , ์บ์ฑ, ๋๊ธฐํ, ์ ๋ฐ์ดํธํ๋ ์์ ์ ์ฝ๊ฒ ์ํํ ์ ์๋๋ก ๋์์ฃผ๋ ๋ชจ๋์ด๋ค๋ผ๊ณ ๋งํ๋ค.
์ฌ์ค ๊ทธ๋ ๊ฒ ๊ท๋ชจ์๋ ํ๋ก์ ํธ๋ฅผ ํด๋ณด๊ฑฐ๋ ์ฌ์ฉ์๊ฐ ์์ฒญ๋๊ฒ ๋ง์ ์๋น์ค๋ฅผ ๊ด๋ฆฌํด๋ณธ ๊ฒฝํ์ด ์์ด์ ๊ทธ๋ฐ์ง ๊ธฐ์กด์ ์์ ๋ถ๋ถ์ ํฌ๊ฒ ๋ถํธํจ์ ๋๋ผ์ง ๋ชปํ์๋ค.
๊ทผ๋ฐ ์ฐธ ์ ๊ธฐํ๊ฒ ์ด๋ฒ ํ๋ก์ ํธ๋ฅผ ํ๋ฉด์๋ ๋ถํธํ ์ ์ ๋๊ผ์๋ค.
์ฌ์ค ์ด๋ฒ ํ๋ก์ ํธ์ ๋ฆฌ์กํธ ์ฟผ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ด์ผํ๋๋ฐ ์ต์์น์์์ ์ฒ์์ ๋ด๊ฐ ํ๋ ๋ฐฉ์๋๋ก api ํธ์ถ์ ํ์๋ค.
๊ทธ๋ฌ๋ค๋ณด๋ ์๋์น์๊ฒ ๋ถํธํ ์ ์ ๋๋ผ๊ณ ํด๊ฒฐํ ์ ์ด ๋๋ค,,,ํธํธ,,
๋ด๊ฐ ๋๋ ๋ถํธํจ์ ํ๋ฉด์ ์ด๊ธฐ ๊ตฌ๋ํ ๋ apiํธ์ถ์ ํ๋ฉด ๋ก๋ฉ์ด ์ค๋๊ฑธ๋ฆฐ๋ค๋ ๊ฒ์ด์๋ค
์ด๋ฒ ํ๋ก์ ํธ๊ฐ React Native๋ก ์ด๋ฃจ์ด์ง ์ดํ์ ๋ง๋๋ ๊ฒ์ด๋ค๋ณด๋๊น ๋ก๋ฉํ๋ฉด ํ๋ํ๋์ ๊ต์ฅํ ๋ถํธํจ์ด ํฌ๊ฒ ๋๊ปด์ก์๋ค.
๋๋ sns์๋น์ค์ ํ๋กํ ๋ถ๋ถ์ ๋ด๋นํ์๋๋ฐ ํ๋กํํ์ด์ง๋ ์๊ฐํด๋ดค์ ๋ ํ๋กํ์ฌ์ง, ๋๋ค์, ๊ณ์ ์ด๋ฆ, ํ๋ก์, ํ๋ก์, ํฌ์คํธ ๋ฑ ๋ถ๋ฌ์ฌ ์ ๋ณด๋ค์ด ๋ง๋ค.
์ด๊ฒ ํ api๋ก ์จ๋ค๋ฉด ์ข๊ฒ ์ง๋ง, ๋ ๋ถ๋ฆฌ๊ฐ ๋์ด์ ์ค๋ ๊ฒฝ์ฐ๋ ๋ง๋ค.
๊ทธ๋ฌ๋ฉด ํ๋์ api๋ฅผ ํธ์ถํ๋๋ฐ๋ ์๊ฐ์ด ๊ฑธ๋ฆฐ๋ค!? ๊ทธ๋ ๋ค๋ฉด ์ฌ๋ฌ api๋ฅผ ๋ถ๋ฅธ๋ค๋ฉด??
๊ทธ๋ ๋ค๋ฉด ๋ ์ค๋๊ฑธ๋ฆฌ๋๊ฑฐ๋ค,,
์์ธ์ง ๋ชจ๋ฅด๊ฒ ์ฑ์์์ ๋ก๋ฉ์ด ์น์์์ ๋ก๋ฉ๋ณด๋ค ์ฒด๊ฐ์ ์ผ๋ก ๊ธธ๊ฒ ๋๊ปด์ง๋ ๊ฒ ๊ฐ์๋ค. ํ๋ฉด์ด ์์์ ๊ทธ๋ฐ๊ฐ..?
๋ญ๊ฐ ์ฑ์ ์น๋ณด๋ค ๋ ์์ ํ๋ฉด์์ ํ์ด์ง๊ฐ ์ด๋์ด ๋น ๋ฅด๊ฒ ๋ํ๋๊ธฐ๋๋ฌธ์ ๊ทธ๋ ๊ฒ ๋๋๋ค๊ณ ํผ์ ์๊ฐํ๋ค.
ํ์ฌ๊ฐ ์ด api๋ฅผ ํธ์ถํ๋๋ผ ๋นํ๋ฉด์ด ๋์ค๋ ์๊ฐ์ด ๊ธธ๋ค๊ณ ๋๊ปด์ง๋ ๊ฑด ๋๋ฟ๋ง ์๋๋ผ ํ์๋ค๋ ๊ทธ๋ ๊ฒ ๋๊ผ๊ธฐ ๋๋ฌธ์ ์ด๋ฅผ ๊ฐ์ ํ ๋ ๋ค๋ฅธ ์ถ๊ฐ์ ์ธ ๊ฐ์ ๋ฐฉ๋ฒ๋ ์์์ง๋ง React-query๋ ํ ๋ชซํ๋ค.
์ผ๋จ ๋ด๊ฐ ๋๋ ์ ์ผ ์ข์๋ ๊ธฐ๋ฅ ์ค์ ํ๋๋ ๋ญ๋๋ญ๋ํด๋ '์บ์ฑ', '์๋ฌํธ๋ค๋ง'์ด์๋ค.
๊ทธ๋ฆฌ๊ณ ๋นผ๋์ ์ ์๋ '์ฝ๋๊ฐ ๋จ์ํด์ง'์ด ๊ต์ฅํ ์ฅ์ ์ด๋ค.
์ฝ๋์ ๋จ์ํ
๋ด๊ฐ ์ฐธ๊ณ ํ๋ ์ํฐํด์ค์ ๋ฆฌ์กํธ ์ฟผ๋ฆฌ๋ฅผ ํตํด BoilerPlate์ ๊ฐ์๋ฅผ ์์ ๊ผฝ์๋ค.
์ฌ์ค ๋ฆฌ๋์ค๋ฅผ ์ฌ์ฉํ๋ฉด ์ ์ผ ๋จผ์ ๊ฒช๋ ๋ฌธ์ ์ค์ ํ๋๊ฐ ๋ฌ๋์ปค๋ธ์ด๋ค.
๋ฌผ๋ก ํ์ตํ ๋์๋ ๊ต์ฅํ ๋ฌ๋์ปค๋ธ๊ฐ ์์ง๋ง, ๋์ ์ ์์ด์๋ ๊ต์ฅํ ๋ง์ ์ฝ๋์ ์์ด ์ ํ์ง๊ณ , ๋ก์ง์ ์ผ๋ก ์ด๋ฃจ์ด์ก๋ค๊ณ ํ ์ ์๋ค.
๋ฆฌ๋์, ์ก์ , ์ํ ๋ฑ๋ฑ ๋ถ๋ฆฌ๊ฐ ๋์ด์์ด ๊ต์ฅํ ๋ถ๊ธฐ์ฑ์ด ์ข์ง๋ง, ๊ทธ๋งํผ ์ ์ด์ผํ๋ ์ฝ๋์ ์์ด ๋ง์๋ค.
๋ฆฌ์กํธ ์ฟผ๋ฆฌ์์๋ ์ฝ๋๊ฐ ๋์ผ๋ก ๋ด๋ ํ์ค์๋ค.
const userInfo = useQuery<UserProfile>(['userProfile', userId], () =>
getUserProfile(userId),
);
์ด ํ์ ํ๋๋ก api ํธ์ถ ํธ๋ค๋ง์ด ๊ฐ๋ฅํด์ง๋ค.
์ฝ๋์ ๋จ์ํ๋ผ๊ณ ํ๋ฉด ๋ฐ๋ผ๋ถ๋ ๊ฒ๋ค ๊ฐ๋ ์ฑ,,์ ์ง๋ณด์์ ์ด์ ,,์ด๋ค.
๊ฐ๋ ์ฑ์ ๋ด๊ฐ ์ค๊ฐ ํฌ์ ๋ผ์ ์ฝ๋๋ฅผ ๋ดค๋ ํ๋ก์ ํธ๋ผ react query๋ฅผ ์ ์ฉํ๋๋ฐ ํฐ ์ด๋ ค์์ด ์์๋ค๋ ๊ฑธ ํตํด ์ ์ ์์๊ณ , ์ ์ง๋ณด์๋.. ์ผ๋จ ํฌ๊ฒ ๋๋ ๋ถ๋ถ์ ์์ง๋ง, ์ฐ์์ ์ผ๋ก ๋ด๊ฐ ์ดํดํ๊ธฐ ์ฌ์ฐ๋ฉด ์์ ํ๊ฑฐ๋ ์ ์ฉํ๋๋ฐ๋ ์ฉ์ดํ ํ ๋๊น ์ ์ง๋ณด์์ ์์ด ์ฉ์ดํ ๊ฒ์ด๋ผ๋ ๊ฒ์ ์ด๋ฆผ์ง์ํ ์ ์๋ค.
API ํธ์ถ ํธ๋ค๋ง
๋ฆฌ๋์ค๋ก ๋น๋๊ธฐ์ฒ๋ฆฌ๋ฅผ ํด์ฃผ๊ธฐ ์ํด์๋ ๋ฏธ๋ค์จ์ด๋ถํฐ state ๊ตฌ์กฐ๊น์ง ๊ต์ฅํ ๋ณต์กํ๊ฒ ์๊ฐํ๊ณ ์ค๊ณํด์ผํ๋ค.
์์์ ๋ฆฌ์กํธ ์ฟผ๋ฆฌ๋ ์์ ์๊ฒ ๋น๋๊ธฐ ์ํ๊ด๋ฆฌ๋ฅผ ์ํด ๋ง๋ค์ด์ก๋ค๊ณ ๊ณต์๋ฌธ์์ ์์ฑ๋์ด์๋๋งํผ ๋ค๋ฐฉ๋ฉด์์ ๋์์คฌ๋ค.
๋ฆฌ์กํธ ์ฟผ๋ฆฌ์์๋ ๋จ์ํ ์ต์ (๋ด๊ฐ ์ฌ์ฉํ๋๊ฑด isLoading,,)๋ค์ ์ฌ์ฉํด์ ์ฝ๊ฒ ํธ๋ค๋งํ ์ ์๊ณ , ์ฌ์ฉ์๊ฒฝํ๊น์ง ์ฝ๊ฒ ๋์ผ ์ ์๋ค.
์ด๋ฐ ์๋ฌํธ๋ค๋ง์ ํตํด ์๋ฌ๋ฉ์์ง๋ฅผ ๋์ด๋ค๋์ง์ ๊ฐ์ UX๋ฅผ ๊ณ ๋ คํ ๊ธฐ๋ฅ๋ค์ ์๊ฐํด๋ณผ ์ ์๋ค.
const postIdList = useInfiniteQuery(
['FeedPostList', userId],
({pageParam}) => getPostIds(userId, {pageParam}),
{
getNextPageParam: (lastPage, pages) => {
if (lastPage.data.last === false) {
return pages.length;
} else {
return undefined;
}
},
},
);
์๋ฅผ ๋ณด๋ฉด useInfiniteQuery๋ฅผ ํตํด ๋ฌดํ์ฌ๋ผ์ด๋?์ ๊ฐ์ ๊ธฐ๋ฅ์ ๊ตฌํํ ์ฝ๋์ด๋ค.
์ด๋ฐ ๊ฒ์ฒ๋ผ ๋ฆฌ์กํธ ์ฟผ๋ฆฌ์์์ ์ฉ์ดํ ๊ธฐ๋ฅ๋ค์ ๊ฐ์ง๊ณ ์ฝ๊ฒ ๊ตฌํํ ์ ์๋ ๋ฐฉ๋ฒ๋ค์ด ๋ง๋ค.
์บ์ฑ
๋ญ๋๋ญ๋ํด๋ ์บ์ฑ
๋ด๊ฐ ๋ฆฌ์กํธ ์ฟผ๋ฆฌ์ ์บ์ฑ์ ๊ฐํธํ๋ค๋ผ๊ณ ๋๋ ๊ฒ์ ๋ฐ๋ก key๋๋ฌธ์ธ๊ฒ๊ฐ๋ค.
const likeMutation = useMutation({
mutationFn: () => putPostLike(postId),
// When mutate is called:
onMutate: async () => {
// Cancel any outgoing refetches
// (so they don't overwrite our optimistic update)
await queryClient.cancelQueries({queryKey: ['post', postId]});
// Snapshot the previous value
const previousPost = queryClient.getQueryData<FeedPost>(['post', postId]);
if (!previousPost) {
return null;
}
// Optimistically update to the new value
if (previousPost?.isLike) {
queryClient.setQueryData(['post', postId], {
...previousPost,
isLike: false,
likeCount: previousPost.likeCount - 1,
});
} else {
queryClient.setQueryData(['post', postId], {
...previousPost,
isLike: true,
likeCount: previousPost.likeCount + 1,
});
}
return {previousPost};
},
onError: (_err, _newTodo, context) => {
queryClient.setQueryData(['post', postId], context?.previousPost);
},
onSettled: () => {
queryClient.invalidateQueries({queryKey: ['post', postId]});
},
});
useMutate๋ฅผ ํตํด์ ์๋ฒ์ ์ํ๋ฅผ ๋ณ๊ฒฝ์ํฌ ์ ์๋ค.
์ด ์์์ key์ setQueryData, invalidateQueries ๋ฑ์ ํตํด ๋ถ๋ฆฌํด์ ํด๋น key์ ํด๋น๋๋ ๋ฐ์ดํฐ๋ฅผ ๊ธฐ๋กํ๊ณ , ์ญ์ ํ๊ณ , ๊ฐฑ์ ํ๋ ์ด๋ฐ ๋์๋ค์ ๊ตฌํํ ์ ์๋ค.
์ด๋ฐ ์บ์ฑ์ด ๋ํํ ๋ ๋ญ๊ฐ ํ๋ช ์ ์ผ๋ก ๋ค๊ฐ์๋ค. ๋น์ทํ ์ ๋ณด๋ฅผ ์์ด๋๊ฐ์ ๋ฐ๋ผ ๋ค๋ฅธ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๋ ๊ฒ์ฒ๋ผ ์์ฉํ๋ฉด์ ๋ญ๊ฐ ๋งํ ์ ์๋ ํธ๋ฆฌํจ?์ ๋๊ผ๋ค..
์ด๋ฐ ํธ๋ฆฌํจ ํ๋ํ๋๊ฐ ์์ฌ ๊ฐ์ธ์ ์ผ๋ก ๊ฐ๋ฐํจ์ ์์ด์ ๋ด๊ฐ ์ด ์ฝ๋์ ํท๊ฐ๋ฆฌ๊ฒ ๋ฐ์ํ๋ ๊ฒ ์์ด ๋ก์ง์ ๊ตฌํํ ์ ์์๋ค.
์ ๋ง ๊ฐ์ธ์ ์ผ๋ก ๋ฌํํ๊ฒ ๋๋ ์ ๋ค์ด๋ผ์ ๋ง์ง ์๋ ์ ๋ณด๊ฐ ์์ ์๋ ์๋๋ฐ ๊ทธ๋ฐ๊ฒ๋ค์ ์๋ ค์ฃผ์๋ฉด ์ข์๊ฒ๊ฐ๋ค.
์์ง ํ๋ก์ ํธ๊ฐ ๋๋์ง ์์์ผ๋ ๊ณ์ ์ฌ์ฉํด๋ณด๊ณ ๋ค์ ๋ ๋ค๋ฅธ ๋๋์ผ๋ก ํ๊ณ ?๊ธ์ ์์ฑํด๋ณผ ์ ์๋ ๊ฒฝํ์ด ๋ ๋ฐ์ํ์ผ๋ฉด ์ข๊ฒ ๋ค๐
์ฐธ๊ณ
https://tanstack.com/query/v3/
https://tech.kakao.com/2022/06/13/react-query/
https://www.youtube.com/watch?v=41tFNtwWE3o