07. ๐ก ์๋ฒ ์ํ ๊ด๋ฆฌ์ ์บ์ฑ ์ ๋ต ๋ง์คํฐ
๐ ๊ฐ์
React Query(TanStack Query)๋ฅผ ํตํด ์๋ฒ ๋ฐ์ดํฐ๋ฅผ '์ํ'๊ฐ ์๋ '์บ์'๋ก ๋ค๋ฃจ๋ ํจ๋ฌ๋ค์ ๋ณํ๋ฅผ ์ดํดํฉ๋๋ค.
๐ ์ด ๋ฉด์ ํญ๋ชฉ์ ๋ชฉํ
โฑ๏ธ ์์ ์ฝ๊ธฐ ์๊ฐ: 24๋ถ (ํต์ฌ ์์ฝ: 12๋ถ)
๐บ๏ธ ์ด ์ฑํฐ์ ํ๋ฆ
[๊ฐ๋
์ฌ์ ] โ [์ง๋ฌธ 1: ํด๋ผ์ด์ธํธ ์ํ vs ์๋ฒ ์ํ] โ [์ง๋ฌธ 2: ์บ์ฑ ๋ฐ ์ ์ ๋ ๊ด๋ฆฌ] โ [์ค์ ๋ณํ ์ง๋ฌธ]
๐ฏ ์ด ์ฑํฐ๋ฅผ ๋ค ์ฝ์ผ๋ฉด ํ ์ ์๋ ๊ฒ
- ์ ์๋ฒ ๋ฐ์ดํฐ๋ฅผ ์ ์ญ ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ(Zustand ๋ฑ)์ ์ ์ฅํ๋ฉด ์ ๋๋์ง ์ค๋ช ํฉ๋๋ค.
Stale-While-Revalidate์ ๋ต์ด ์ฌ์ฉ์ ๊ฒฝํ์ ์ด๋ป๊ฒ ๊ทน๋ํํ๋์ง ์ดํดํฉ๋๋ค.- ๋ฌดํ ์คํฌ๋กค, ๋๊ด์ ์ ๋ฐ์ดํธ ๋ฑ ๋ณต์กํ ๋น๋๊ธฐ ํจํด์ ๊ตฌํ ์๋ฆฌ๋ฅผ ๋ง์คํฐํฉ๋๋ค.
๐ ํต์ฌ ๊ฐ๋ ์ฌ์ (Concept Glossary)
1. ์๋ฒ ์ํ (Server State)
๋ด๊ฐ ์์ ํ์ง ์์, ์๊ฒฉ์ง์ DB์ ์ ์ฅ๋ ๋ฐ์ดํฐ์ ๋๋ค. ์ธ์ ๋ ๋ค๋ฅธ ์ฌ์ฉ์์ ์ํด ๋ฐ๋ ์ ์์ผ๋ฉฐ(Out-of-sync), ๊ฐ์ ธ์ค๋ ๋ฐ ์๊ฐ์ด ๊ฑธ๋ฆฌ๋ ๋น๋๊ธฐ์ ํน์ฑ์ ๊ฐ์ง๋๋ค.
2. SWR (Stale-While-Revalidate)
"์ํ(Stale) ๋ฐ์ดํฐ๋ฅผ ๋จผ์ ๋ณด์ฌ์ฃผ๋, ๊ทธ๋์ ์๋ฒ์์ ์ ์ ํ(Fresh) ๋ฐ์ดํฐ๋ฅผ ๋ค์ ๊ฐ์ ธ์(Revalidate) ์กฐ์ฉํ ๊ต์ฒดํ๋ค"๋ ์บ์ฑ ์ ๋ต์ ๋๋ค. ์ฌ์ฉ์์๊ฒ '๋๊ธฐ ์๊ฐ 0'์ ๊ฒฝํ์ ์ค๋๋ค.
3. ๋๊ด์ ์ ๋ฐ์ดํธ (Optimistic Update)
์๋ฒ์ ์๋ต์ด ์ค๊ธฐ๋ ์ ์ ๋ฏธ๋ฆฌ UI๋ฅผ '์ฑ๊ณต'ํ ๊ฒ์ฒ๋ผ ๋ฐ๊พธ๋ ๊ธฐ๋ฒ์ ๋๋ค. ์ข์์ ๋ฒํผ์ด๋ ๋๊ธ ์์ฑ์ฒ๋ผ ๋น ๋ฅด๊ธฐ ์ฐจ์ด๊ฐ UX์ ํฐ ์ํฅ์ ์ฃผ๋ ๊ธฐ๋ฅ์ ํ์์ ์ ๋๋ค.
๐บ๏ธ ์ด ๋ฌธ์์ ๋ฐฐ๊ฒฝ ์ธ๊ณ๊ด: '์์๋ค ์ปค๋ฎค๋ํฐ'
- ๐ฃ ์์ฒ ( ์ ์
): "์ํธ ๋! '์์๋ค ๊ฒ์ํ' ๋ฐ์ดํฐ๋ฅผ Redux์ ์ ์ฅํ๊ณ ๊ด๋ฆฌํ๋๋ผ
Loading,Error,Success์ํ ๋ณ์๋ง 6๊ฐ๋ฅผ ๋ง๋ค์์ด์. ๋น๋๊ธฐ ์ฝ๋ ์ง๋ค๊ฐ ๋์ด๋ฒ๋ฆด ๊ฒ ๊ฐ์์... ๐ด" - ๐ฆ ์ํธ ( ๋ฆฌ๋ ): "์์ฒ ๋, ์๋ฒ ๋ฐ์ดํฐ๋ '์ํ'๊ฐ ์๋๋ผ '์๊ฒฉ ์ค๋ ์ท'์ ๋๋ค. ๊ทธ๊ฑธ ๊ตณ์ด ์ฐ๋ฆฌ ์ฑ ์ํ์ ์ต์ง๋ก ๋ผ์ ๋ง์ถ๋ ค๋๊น ํ๋ ๊ฑฐ์์. React Query ๊ฐ์ ๋๊ตฌ์๊ฒ '๊ด๋ฆฌ'๋ฅผ ๋งก๊ธฐ๊ณ ์ฐ๋ฆฌ๋ ๊ทธ์ '๊ตฌ๋ '๋ง ํ๋ฉด ๋ฉ๋๋ค."
Q1. ํด๋ผ์ด์ธํธ ์ํ(Client State)์ ์๋ฒ ์ํ(Server State)๋ฅผ ๋ช ํํ ๊ตฌ๋ถํด์ผ ํ๋ ์ด์ ๋ ๋ฌด์์ธ๊ฐ์?
๐ฏ ์ถ์ ์๋
๋ฐ์ดํฐ์ ์์ ๊ถ๊ณผ ์๋ช ์ฃผ๊ธฐ๋ฅผ ์ดํดํ๊ณ ์๋์ง ํ์ธํฉ๋๋ค. ์ด๋ฅผ ๊ตฌ๋ถํ์ง ๋ชปํ๋ฉด ๋ถํ์ํ ๋ณด์ผ๋ฌํ๋ ์ดํธ ์ฝ๋์ ๋ฐ์ดํฐ ๋ถ์ผ์น(Data Inconsistency) ๋ฒ๊ทธ์ ์๋ฌ๋ฆฌ๊ฒ ๋ฉ๋๋ค.
๐ฃ ์์ฒ ์ด์ Naive ๊ตฌํ (Bad Case)
์์ฒ ์ด๋ ๋ชจ๋ API ์๋ต์ ์ ์ญ ์คํ ์ด์ ๊พธ์ญ๊พธ์ญ ์ง์ด๋ฃ๊ณ ์์ต๋๋ค.
// ๐ฃ ์์ฒ : "์ ์ ๋ชฉ๋ก๋ ์ ์ญ ์ํ๋๊น Redux์ ์ ์ฅํด์ผ์ง!"
function Users() {
const dispatch = useDispatch();
const { data, isLoading } = useSelector(state => state.users);
useEffect(() => {
dispatch(fetchUsers()); // โ ๏ธ ๋ก๋ฉ, ์๋ฌ, ์บ์ ๋ฌดํจํ ๋ก์ง์ ์ง์ ๋ค ๊ตฌํํด์ผ ํจ
}, []);
// โ ๏ธ ๋ฌธ์ : ๋ค๋ฅธ ํญ์์ ์ ์ ๊ฐ ์ถ๊ฐ๋์ด๋ ์ด ์ฑ์ ์ ๋ฐฉ๋ฒ์ด ์์ (Outdated)
}๐ฆ ์ํธ์ ํฉํญ ์กฐ์ธ
"์์ฒ ๋, ์ ์ ๋ชฉ๋ก์ ์ฐ๋ฆฌ ์ฑ์ด ์ฃผ์ธ์ด ์๋์์. ์๋ฒ๊ฐ ์ฃผ์ธ์ด์ฃ . ๋ฐ์ดํฐ๊ฐ ๋ฐ๋๋ฉด ์๋ฒ๊ฐ ์๋ ค์ฃผ๊ฑฐ๋ ์ฐ๋ฆฌ๊ฐ ๋ค์ ๋ฌผ์ด๋ด์ผ ํฉ๋๋ค. ํด๋ผ์ด์ธํธ ์ํ(๋คํฌ๋ชจ๋ ์ฌ๋ถ ๋ฑ)์๋ ์์ ํ ๋ค๋ฅธ ์ํ๊ณ์์."
๐ฆ ์ํธ์ ์ํคํ ์ฒ ๊ฐ์ด๋ (Good Case)
์ํธ ๋ฆฌ๋๋ React Query๋ฅผ ์ฌ์ฉํด ์ ์ธ์ ์ผ๋ก ์๋ฒ ๋ฐ์ดํฐ๋ฅผ ๋ค๋ฃจ๋ ๋ฒ์ ๋ณด์ฌ์ค๋๋ค.
// ๐ฆ ์ํธ: "๋ฐ์ดํฐ ํ์นญ์ '๋ช
๋ น'์ด ์๋๋ผ '์ ์ธ'์
๋๋ค."
function Users() {
// โ
๋ก๋ฉ, ์๋ฌ, ๋ฐ์ดํฐ, ์ ์ ๋ ์ฒดํฌ๊น์ง ํ ์ค๋ก ํด๊ฒฐ
const { data, isLoading, error } = useQuery({
queryKey: ['users'],
queryFn: fetchUsers,
staleTime: 1000 * 60 * 5, // 5๋ถ ๋์์ ์ ์ ํ ๋ฐ์ดํฐ๋ก ๊ฐ์ฃผ (์บ์ ํ์ฉ)
});
if (isLoading) return <Spinner />;
return <div>{data.map(user => <div key={user.id}>{user.name}</div>)}</div>;
}๐ ๋ ๋ฒจ๋ณ ๋ต๋ณ ๊ฐ์ด๋ (Self-Check)
- Level 1 (Junior): "์๋ฒ ์ํ๋ API๋ก ๊ฐ์ ธ์ค๋ ๋ฐ์ดํฐ๊ณ , ํด๋ผ์ด์ธํธ ์ํ๋ UI์ฉ ๋ฐ์ดํฐ์ ๋๋ค. ์๋ฒ ๋ฐ์ดํฐ๋ ๋ก๋ฉ ์ฒ๋ฆฌ๊ฐ ํ์ํฉ๋๋ค."
- Level 2 (Senior): "์์ ๊ถ(Ownership)์ ์ฐจ์ด๋ฅผ ์ค๋ช ํฉ๋๋ค. ์๋ฒ ์ํ๋ ๋น๋๊ธฐ์ ์ด๊ณ ๋๊ธฐํ๊ฐ ํ์ํ๋ฉฐ ์ฌ๋ฌ ์ฌ์ฉ์๊ฐ ๊ณต์ ํ๋ค๋ ์ ์ ์ง์ ํฉ๋๋ค. ์ด๋ฅผ ์ํด ์บ์ฑ, ์ค๋ณต ์์ฒญ ๋ฐฉ์ง, ๋ฐฑ๊ทธ๋ผ์ด๋ ์ ๋ฐ์ดํธ ๋ฑ์ด ํ์ํจ์ ๊ฐ์กฐํฉ๋๋ค."
- Level 3 (Specialist): "์๋ฒ ์ํ ๊ด๋ฆฌ๊ฐ ๋ณต์กํ ๋น์ฆ๋์ค ์ ํ๋ฆฌ์ผ์ด์ ์์ ์ด๋ป๊ฒ 'SSOT(Single Source of Truth)' ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋์ง ๋ถ์ํฉ๋๋ค. ์๋ฒ ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ๋ฆฌ์กํธ์ '์ ์ธ์ UI' ํจ๋ฌ๋ค์๊ณผ ์ด๋ป๊ฒ ์ผ์นํ๋์ง, ๊ทธ๋ฆฌ๊ณ ์ด๋ก ์ธํด ์ ์ญ ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์ญํ ์ด '์์ UI ์ํ'๋ก๋ง ์ถ์๋๋ ์ํคํ ์ฒ์ ์ฐ์ํจ์ ์ค๋ช ํฉ๋๋ค."
Q2. staleTime๊ณผ cacheTime์ ์ฐจ์ด๋ฅผ ์ค๋ช ํ๊ณ , ์ด๋ฅผ ํ์ฉํ ์ต์ ์ ์บ์ ์ ๋ต์ ์ ์ํด ๋ณด์ธ์.
๐ฏ ์ถ์ ์๋
React Query์ ํต์ฌ ๋งค์ปค๋์ฆ์ธ '์ ์ ๋'์ '๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ'๋ฅผ ์ ํํ ์ดํดํ๊ณ ์ํฉ์ ๋ง๊ฒ ํ๋ํ ์ ์๋์ง ํ์ธํฉ๋๋ค.
๐ฃ ์์ฒ ์ด์ Naive ๊ตฌํ (Bad Case)
์์ฒ ์ด๋ ๋ชจ๋ API ์์ฒญ์ ๋ํด ๊ธฐ๋ณธ ์ค์ ๋ง ์ฐ๊ณ ์์ต๋๋ค.
// ๐ฃ ์์ฒ : "์ค์ ๊ฐ์ด ๋๋ฌด ๋ง์์ ๊ทธ๋ฅ ๊ธฐ๋ณธ์ผ๋ก ์จ์. ์์์ ์ ๋๊ฒ ์ฃ ?"
const { data } = useQuery({ queryKey: ['posts'], queryFn: fetchPosts });
// โ ๏ธ ๋ฌธ์ : ํ์ด์ง๋ฅผ ์ ๊น ๋๊ฐ๋ค ์ฌ ๋๋ง๋ค ๋งค๋ฒ API ์ฌํธ์ถ ๋ฐ์ (์๋ฒ ๋ถํ)๐ฆ ์ํธ์ ํฉํญ ์กฐ์ธ
"์์ฒ ๋, ๊ฒ์๊ธ ๋ชฉ๋ก์ 1์ด ๋ง์ ์ ๋ฐ๋์ด์. ๊ทธ๋ฐ๋ฐ ์ ๋งค๋ฒ ์๋ฒ๋ฅผ ๊ดด๋กญํ๋์? ๋ฐ์ดํฐ๋ฅผ ์ผ๋ง๋ '์ ์ (Fresh)'ํ๋ค๊ณ ๋ฏฟ์ด์ค์ง ๊ฒฐ์ ํ๋ ๊ฒ ์๋์ด์ ์ธ์ฌํจ์ ๋๋ค."
๐ฆ ์ํธ์ ์ํคํ ์ฒ ๊ฐ์ด๋ (Good Case)
์ํธ ๋ฆฌ๋๊ฐ ์ํฉ์ ๋ฐ๋ฅธ ์บ์ ์ค์ ๋ฒ์ ์ ์ํฉ๋๋ค.
// ๐ฆ ์ํธ: "๋ฐ์ดํฐ์ ์ฑ๊ฒฉ์ ๋ฐ๋ผ ์ ํต๊ธฐํ์ ์ ํ์ธ์."
// 1. ๊ณต์ง์ฌํญ: ์ ์ ๋ณํจ -> staleTime์ ๊ธธ๊ฒ (์: 1์๊ฐ)
const noticeQuery = useQuery({
queryKey: ['notices'],
staleTime: 1000 * 60 * 60,
});
// 2. ์ค์๊ฐ ์ฑํ
: ๊ณ์ ๋ณํจ -> staleTime์ 0 (๋งค๋ฒ ์ฌ๊ฒ์ฆ)
const chatQuery = useQuery({
queryKey: ['chats'],
staleTime: 0,
});
// ๐ก ํ: cacheTime์ ๋ฐ์ดํฐ๊ฐ ๋ฉ๋ชจ๋ฆฌ์ ๋จ์์๋ ์๊ฐ(Unused data)์
๋๋ค.
// ๋ณดํต staleTime๋ณด๋ค ๊ธธ๊ฒ ์ค์ ํ์ฌ ํ์ด๋๋ ์ด์
์ ์ด์ ์ ์ป์ต๋๋ค.๐ ๋ ๋ฒจ๋ณ ๋ต๋ณ ๊ฐ์ด๋ (Self-Check)
- Level 1 (Junior): "staleTime์ ๋ฐ์ดํฐ๊ฐ ์ ์ ํ ์๊ฐ์ด๊ณ , cacheTime์ ๋ฉ๋ชจ๋ฆฌ์ ๋จ์์๋ ์๊ฐ์ ๋๋ค."
- Level 2 (Senior): "๋ฐ์ดํฐ๊ฐ 'stale'ํด์ ธ๋ ์ฆ์ ์ฌ๋ผ์ง์ง ์๊ณ , ๋ฐฑ๊ทธ๋ผ์ด๋ ์ฌ๊ฒ์ฆ(Revalidation) ํธ๋ฆฌ๊ฑฐ๊ฐ ๋จ์ ์ค๋ช ํฉ๋๋ค. cacheTime์ ๊ฐ๋น์ง ์ปฌ๋ ํฐ๊ฐ ์๋ํ๊ธฐ ์ ๊น์ง์ ์ฌ์ ์๊ฐ์์ ๋ช ํํ ๊ตฌ๋ถํฉ๋๋ค."
- Level 3 (Specialist): "์ฌ์ฉ์ ๊ฒฝํ ๊ด์ ์์
staleTime์ ๋ฌดํ(Infinity)์ผ๋ก ๋๊ณInvalidate๋ฅผ ์๋์ผ๋ก ์กฐ์ ํ๋ '์ ์ ๋ฐ์ดํฐ ๊ด๋ฆฌ' ์ ๋ต์ ์ค๋ช ํฉ๋๋ค. ๋๋Prefetching๊ณผ ๊ฒฐํฉํ์ฌ ๋ค์ ํ์ด์ง ๋ฐ์ดํฐ๋ฅผ ๋ฏธ๋ฆฌstale์ํ๋ก ์บ์์ ๋ฃ์ด๋์ด ์ ํ ์๋๋ฅผ 0์ผ๋ก ๋ง๋๋ ๊ธฐ๋ฒ์ ์ ์ํฉ๋๋ค."
๐ ์ค์ ๋ณํ ์ง๋ฌธ (Related Variations)
Q72. ์ฟผ๋ฆฌ ๋ฌดํจํ(Invalidation)์ ์๋ ์ ๋ฐ์ดํธ(SetQueryData)์ ์ฐจ์ด์ ์ ๋ฌด์์ธ๊ฐ์?
- ๐ฏ ์ถ์ ์๋: ๋ฐ์ดํฐ ์ผ๊ด์ฑ์ ์งํค๋ ๋ ๊ฐ์ง ์ ๋ต์ ํธ๋ ์ด๋์คํ๋ฅผ ์ดํดํ๋์ง ํ์ธํฉ๋๋ค.
- ๐ก ํต์ฌ ์๋ฆฌ & ๋ต๋ณ:
Invalidate๋ "์ด ๋ฐ์ดํฐ๋ ์ํ์ผ๋ ์๋ฒ์์ ๋ค์ ๋ฐ์์!"๋ผ๊ณ ์ ์ธํ๋ ์์ ํ ๋ฐฉ์์ด๋ฉฐ, ํญ์ ์ต์ ๋ฐ์ดํฐ๋ฅผ ๋ณด์ฅํฉ๋๋ค. ๋ฐ๋ฉดSetQueryData๋ ์๋ฒ ์๋ต ์ ์ ์บ์๋ฅผ ์ง์ ์์ ํ๋ '๋๊ด์ ์ ๋ฐ์ดํธ'์ ์ฃผ๋ก ์ฐ์ด๋ฉฐ, ๋คํธ์ํฌ ์์ฒญ์ ํ ๋ฒ ์๋ ์ ์์ด ํจ์ฌ ๋น ๋ฆ ๋๋ค. ํ์ง๋ง ์ง์ ๋ฐ์ดํฐ๋ฅผ ์กฐ์ฌ์ค๋ฝ๊ฒ ์กฐ์ํด์ผ ํ๋ฏ๋ก ๋ณต์ก๋๊ฐ ๋๊ณ ์คํจ ์ ๋กค๋ฐฑ ๋ก์ง์ด ํ์์ ๋๋ค.
Q85. ๋ฌดํ ์คํฌ๋กค(Infinite Scroll) ๊ธฐ๋ฅ์ ๊ตฌํํ ๋ ๊ณ ๋ คํด์ผ ํ ํต์ฌ ์ฑ๋ฅ ํฌ์ธํธ๋?
- ๐ฏ ์ถ์ ์๋: ๋ฐ์ดํฐ ์์ด ๋์ด๋ ๋ ์๊ธฐ๋ ๋ธ๋ผ์ฐ์ ์ ํ๊ณ์ ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ์กฐํ์ํค๋ ๋ฅ๋ ฅ์ ํ์ธํฉ๋๋ค.
- ๐ก ํต์ฌ ์๋ฆฌ & ๋ต๋ณ: ์ฒซ์งธ,
useInfiniteQuery๋ฅผ ์ฌ์ฉํ์ฌpageParam๋จ์๋ก ๋ฐ์ดํฐ๋ฅผ ๊ด๋ฆฌํ๊ณ ์ด์ /๋ค์ ํ์ด์ง๋ฅผ ๋งค๋๋ฝ๊ฒ ํ์นญํด์ผ ํฉ๋๋ค. ๋์งธ, ๋ ๋๋ง ์ต์ ํ์ ๋๋ค. ๋ฐ์ดํฐ๊ฐ ๋ง์์ง๋ฉด DOM ๋ ธ๋๊ฐ ๋ฌด๊ฑฐ์์ง๋ฏ๋กIntersection Observer๋ ๋ฌผ๋ก , ํ๋ฉด ๋ฐ์ ๋ ธ๋๋ฅผ ์ ๊ฑฐํ๋ '์๋์(Windowing/Virtualization)' ๊ธฐ๋ฒ์ ๋ณํํด์ผ ํฉ๋๋ค. ๋ง์ง๋ง์ผ๋ก ์คํฌ๋กค ์ด๋ฒคํธ ๋๋ฐ์ด์ฑ์ด๋ ์ฐ๋กํ๋ง์ ํตํด ๋ถํ์ํ API ํธ์ถ ํญํ์ ๋ง์์ผ ํฉ๋๋ค.
Q91. ์ฌ๋ฌ ์ปดํฌ๋ํธ์์ ๊ฐ์ Query๋ฅผ ํธ์ถํ ๋, ๋คํธ์ํฌ ์์ฒญ์ด ํ ๋ฒ๋ง ๋ฐ์ํ๋ ์๋ฆฌ๋?
- ๐ฏ ์ถ์ ์๋: ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋ด๋ถ ์บ์ฑ ๋ ์ด์ด์ ์์ฒญ ๋ณํฉ(Request Deduplication) ๋ฉ์ปค๋์ฆ์ ์ดํดํ๊ณ ์๋์ง ํ์ธํฉ๋๋ค.
- ๐ก ํต์ฌ ์๋ฆฌ & ๋ต๋ณ: React Query๋
QueryClient๋ผ๋ ์ ์ญ ์ ์ฅ์๋ฅผ ๊ฐ์ง๊ณ ์์ผ๋ฉฐ, ๋ชจ๋ ์ฟผ๋ฆฌ๋ ๊ณ ์ ํQueryKey๋ฅผ ์๋ณ์๋ก ์ฌ์ฉํฉ๋๋ค. ๋์ผํ ํค๋ก ์ฌ๋ฌ ๋ฒ ์์ฒญ์ด ๋ค์ด์ค๋ฉด, ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ํ์ฌ '์งํ ์ค์ธ ์์ฒญ(Pending Promise)'์ด ์๋์ง ํ์ธํ๊ณ ์๋ค๋ฉด ๋ณ๋์ ๋คํธ์ํฌ ํธ์ถ ์์ด ํด๋น ํ๋ก๋ฏธ์ค๋ฅผ ๊ณต์ ํฉ๋๋ค. ์ด๋ฏธ ์๋ฃ๋ ๋ฐ์ดํฐ๋ผ๋ฉด ์บ์๋ ๊ฐ์ ์ฆ์ ๋ฐํํ๋ฉฐstaleTime์ ๋ฐ๋ผ ๋ฐฑ๊ทธ๋ผ์ด๋ ์ ๋ฐ์ดํธ ์ฌ๋ถ๋ฅผ ๊ฒฐ์ ํฉ๋๋ค. ์ด๋ฅผ ํตํด ์ปดํฌ๋ํธ๊ฐ ํํธํ๋์ด ์์ด๋ ๋ฐ์ดํฐ ์ผ๊ด์ฑ์ ์ ์งํ ์ ์์ต๋๋ค.
๐ฃ ์์ฒ ์ด์ ๋ณต๊ธฐ ์ผ๊ธฐ
์ค๋ '์๋ฒ ์ํ'๋ผ๋ ๊ฐ๋ ์ ๋ฐฐ์ฐ๊ณ ๋์ ๊ทธ๋์ ๋ด๊ฐ ์ ๊ทธ๋ ๊ฒ ๋ถํ(?)ํ๋์ง ์๊ฒ ๋์๋ค. ์๋ฒ ๋ฐ์ดํฐ๋ฅผ ๋ด ์ง์ญ ๋ณ์์ฒ๋ผ ๋ถ๋ฆฌ๋ ค ํ๋ ์ค๋งํจ์ด ๋ฌธ์ ์๋ค. ์ด์ React Query๋ผ๋ ๋ ๋ ํ ํํธ๋์๊ฒ ๋ณต์กํ ๊ฑด ๋งก๊ธฐ๊ณ , ๋๋ ์ฌ์ฉ์์๊ฒ ์ด๋ค ๋ฐ์ดํฐ๋ฅผ ์ผ๋ง๋ ๋นจ๋ฆฌ ๋ณด์ฌ์ค์ง๋ง ๊ณ ๋ฏผํ๋ฉด ๋๋ค.
๐ก "์ต๊ณ ์ ์ ์ญ ์ํ๋ ์์ ์ ์ญ ์ํ์ ๋ฃ์ง ์์๋ ๋๋ ์ํ๋ค."
๋ด์ผ์ ๋ชจ๋ ์น์ ํ์ค, 'Next.js์ ์๋ฒ ์ปดํฌ๋ํธ'์ ์ธ๊ณ๋ก ๋ค์ด๊ฐ๋ค. App Router๋ ๋ ์ผ๋ง๋ ํ๋ช ์ ์ผ์ง, ์ํธ ๋๊ป ์ ๋๋ก ๋ฐฐ์๋ด์ผ์ง! ๐๐ป