๋ฆฌ์กํธ์์๋ ์ญํ ๋ณ๋ก ์ปดํฌ๋ํธ๋ฅผ ๋๋์ด ์ฌ์ฌ์ฉ์ฑ๊ณผ ์ ์ง๋ณด์์ฑ์ ๋์ผ ์ ์์ต๋๋ค. ์ด๋ ๊ฐ ์ปดํฌ๋ํธ ๊ฐ์ ์ํ๋ฅผ ๊ณต์ ํ๋ ์ฌ๋ฌ๊ฐ์ง ๋ฐฉ๋ฒ์ด ์์ต๋๋ค.
Props๋ ๊ฐ์ฅ ๊ธฐ๋ณธ์ ์ธ ๋ฐฉ๋ฒ์ด์ง๋ง, ์ปดํฌ๋ํธ์ ๊น์ด๊ฐ ๊น์ด์ง๋ฉด ๋ถ๋ชจ ์ปดํฌ๋ํธ์์ ์์ ์ปดํฌ๋ํธ๋ก ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๊ธฐ ์ด๋ ค์์ง๋๋ค. ์ด๋ฌํ ๋ฌธ์ ๋ฅผ Prop Drilling์ด๋ผ๊ณ ํฉ๋๋ค.
์ ์ญ์ํ๋ ๋ชจ๋ ์ปดํฌ๋ํธ๊ฐ ์ ๊ทผํ ์ ์๋ ์ํ๋ฅผ ์ ์ํ๋ ๋ฐฉ๋ฒ์
๋๋ค.
์์ฝ๊ฒ ์ํ๋ฅผ ์ ์ํ๊ณ ๊ณต์ ํ ์ ์์ผ๋, ์ปดํฌ๋ํธ ์ฌ์ดํด์ ๋ฒ์ด๋๋ฏ๋ก ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ๋ฅผ ์ํด์ ์๋์ผ๋ก ์ํ๋ฅผ ๊ด๋ฆฌํด์ผ ํฉ๋๋ค.
Context API๋ ํน์ ์ปดํฌ๋ํธ ํธ๋ฆฌ ๋ด์์ ์ํ๋ฅผ ๊ณต์ ํ๋ ๋ฐฉ๋ฒ์
๋๋ค.
์ปดํฌ๋ํธ์ ๋ผ์ดํ์ฌ์ดํด์ ๋ฐ๋ผ ์ํ๊ฐ ๊ด๋ฆฌ๋์ ํธํ์ง๋ง Context์ ์ผ๋ถ ์ํ๊ฐ ๋ณ๊ฒฝ๋๋ฉด ๋ชจ๋ ์ปดํฌ๋ํธ๊ฐ ๋ฆฌ๋ ๋๋ง ๋๋ ๋ฌธ์ ๊ฐ ์์ต๋๋ค.
React Query๋ ์ํ๋ฅผ ์ฌ์ฉํ๋ ์ปดํฌ๋ํธ๊ฐ ์์ผ๋ฉด ์๋์ผ๋ก ์ํ๋ฅผ ์ญ์ ํ๋ ์ต์ ํ๋ฅผ ์ ๊ณตํฉ๋๋ค. ๊ทธ๋ฌ๋ React Query์ ์ฃผ๋ ๋ชฉ์ ์ ์๋ฒ์ ์ํ๋ฅผ ๊ด๋ฆฌํ๋ ๊ฒ์ ๋๋ค.
์ด๋ ๊ฒ ๊ฐ ๋ฐฉ๋ฒ์๋ ํน์ง์ด ์กด์ฌํ๋๋ฐ ์ ๊ฐ ์ํ๋ ์๊ตฌ์ฌํญ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
๊ฒฐ๊ตญ Context API์ React Query์ ๊ฐ ์ฅ์ ์ ๊ฒฐํฉํ ๊ธฐ๋ฅ์ด ํ์ํ์ต๋๋ค. ๊ทธ๋์ Context Query๋ฅผ ๊ฐ๋ฐํ์์ต๋๋ค.
Context Query๋ ๋ชจ๋
ธ๋ ํฌ๋ก ๊ตฌ์ฑ๋์ด ์์ผ๋ฉฐ ์ฝ์ด ํจํค์ง์ ์ฝ์ด ํจํค์ง๋ฅผ ์ด์ฉํด ๊ฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ํ๋ ์์ํฌ์ ๋ง๊ฒ ๊ฐ๋ฐ ํ ์ ์๋๋ก,
์ด๋ํฐ ํจํด์ ์ด์ฉํด ๊ตฌ์ฑ๋ฉ๋๋ค. ์ด๋ ํ์ฌ๋ ๋ฆฌ์กํธ๋ง ์ง์ํ์ง๋ง ์ถํ ํ์ฅ์ฑ์ ์ผ๋ํ ์ํคํ
์ฒ์
๋๋ค.
์ฝ์ด ํจํค์ง๋ ์คํ ์ด ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค. ์คํ ์ด๋ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๊ณ ๋ฐํ ํ ์ ์์ผ๋ฉฐ ์ต์ ๋ฒ ํจํด์ ์ด์ฉํ์ฌ ์ํ๊ฐ ๋ณ๊ฒฝ ๋ ๋ ๋ฑ๋ก๋ ๋ฆฌ์ค๋ ํจ์๋ฅผ ์คํํ๋ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค.
๋ฆฌ์กํธ ํจํค์ง๋ ์คํ ์ด๋ฅผ ์์ฑํ์ฌ ๊ฐ ์ปค์คํ ํ ์์ ์ํ๋ฅผ ๊ตฌ๋ ํ๊ณ ๋ฆฌ์ค๋ ํจ์๊ฐ ์คํ ๋ ๋ ๋ฆฌ์กํธ์ ์ํ๋ฅผ ์ ๋ฐ์ดํธ ํ๋ ๊ตฌ์กฐ๋ก ๋์ด์์ต๋๋ค.
๊ฐ๋ฐ์ ๊ฒฝํ์ ๋์ด๊ธฐ ์ํด ์ฌ๋ฌ๊ฐ์ง๋ฅผ ๊ณ ๋ คํ์ต๋๋ค. ๊ทธ ์ค ํ๋๊ฐ Context ์ธ๋ถ์์ ๋ฐ์ดํฐ๋ฅผ ์ฃผ์
ํ๋ ๋ฐฉ๋ฒ์ ๊ดํ๊ฒ์
๋๋ค
Context Query๋ ๊ฒฐ๊ตญ Context API์ Provider๋ก ๊ตฌ์ฑ๋๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์
๋๋ค. ์ด๋ Provider๋ก ์ด๊ธฐ๊ฐ์ Props๋ก ์ ๋ฌ ํ ์ ์๋ ๊ตฌ์กฐ๋ฅผ ์๋ฏธํฉ๋๋ค.
์ฒ์์๋ ์ด๋ฐ ๋ฐฉํฅ์ผ๋ก ๊ฐ๋ฐ์ ์์ํ์ง๋ง ์ฑ๋ฅ ์ต์ ํ ๋ฌธ์ ์ ๋ถ๋ช์ณค์ต๋๋ค.
props๊ฐ ๋ณ๊ฒฝ๋๋ฉด ๋ฆฌ์กํธ์์๋ ํ์ ์ปดํฌ๋ํธ๋ฅผ ๋ชจ๋ ๋ฆฌ๋ ๋๋ง ํ๋ ๋ฌธ์ ์์ต๋๋ค. ์ฑ๋ฅ์ ์ต์ ํ ํ๋ฉด์ ๊ฐ๋ฐ์๊ฐ Provider ์ธ๋ถ์์ ๋ฐ์ดํฐ๋ฅผ ์ด๊ธฐํ ์ํฌ ์ ์๋ ๋ฐฉ๋ฒ์ ์ ๊ณตํด์ผ ํ์ต๋๋ค.
์ด ๋ฌธ์ ๋ Store์ ๊ธฐ๋ฅ์ ์ด์ฉํด ํด๊ฒฐํ์ต๋๋ค. Provider๋ก Props๋ฅผ ์ ๋ฌํ์ง ์๊ณ Store์ ์ง์ ์ ์ผ๋ก ์ํ๋ฅผ ์
๋ฐ์ดํธํ๊ณ ๊ทธ์ ๋ฐ๋ผ ์ํ๋ฅผ ๊ตฌ๋
ํ๋ ์ปดํฌ๋ํธ๋ค์๊ฒ ์ด๋ฒคํธ๋ฅผ ์ ๋ฌํ๋ ๋ฐฉ์์ด์์ต๋๋ค.
์ด๋ Props๋ฅผ ๊ฑฐ์น์ง ์์ผ๋ฏ๋ก ๋ถํ์ํ ๋ฆฌ๋ ๋๋ง์ ๋ฐ์์ํค์ง ์์์ต๋๋ค.
๊ทธ๋ฆฌ๊ณ ๊ฐ๋ฐ์๊ฐ ์ํ๋ฅผ ์ฝ๊ฒ ๊ตฌ๋ ํ ์ ์๋๋ก ๊ตฌ๋ ํ๊ณ ์ ํ๋ ์ํ์ ๊ฐ ํค๊ฐ์ ๋ฐฐ์ด๋ก ์ ๋ฌํ์ฌ ๋ค์ค ๋๋ ๋จ์ผ๋ก ์ํ๋ฅผ ๊ฐ์ ธ์ฌ ์ ์๊ฒ ํ์์ต๋๋ค.
๋ง์ง๋ง์ผ๋ก Context Query๋ฅผ ๋ง๋ค๊ณ ์ด๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ์์ ๊ฒฐ์ ํ ๋ ์ปดํฌ๋ํธ ๋ด๋ถ์์ ์์ฑํ๋ ๊ฒ์ด ์๋ ์ธ๋ถ์์ ์ ์ธํ์ฌ ํ์ํ ๊ณณ์ ์ฃผ์
ํ๋ ๋ฐฉ์์ ์ ํํ์ต๋๋ค.
์ด๋ Zustand ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ฒ๋ผ ๋น์ทํ ๋ฐฉ์์
๋๋ค. ํจ์๋ฅผ ์ด์ฉํด์ ContextQuery๋ฅผ ์์ฑํ๋ฉด Provider์ ํด๋น ๋ฐ์ดํฐ๋ฅผ ์กฐ์ํ ์ ์๋ ํ
์ ๋ฐํํฉ๋๋ค.
Provider์ ์ปค์คํ ํ ์ ๋ด๋ถ์ ์ผ๋ก ํ๋์ ์คํ ์ด๋ฅผ ๊ณต์ ํ๋ฏ๋ก Provider์ ํ ์ ๊ฐ์ด ์ ๊ณตํ๋ ๊ฒ์ด ๋์ผํ ์ํ๋ฅผ ์กฐ์ํ๊ณ ์ ๊ณตํ๋ ๊ธฐ๋ฅ์์ ์ธ์ง์ํฌ ์ ์๋ค๊ณ ์๊ฐํ์ต๋๋ค.
createContextQuery ํจ์๋ฅผ ์ด์ฉํด ์ด๊ธฐ๊ฐ์ ์ ๋ฌํ๊ณ ์ด์ ๋ฐ๋ผ ํ์
์ด ์๋์ผ๋ก ์ถ๋ก ๋๊ธฐ ๋๋ฌธ์ ์ฌ์ค ์ ๋ค๋ฆญ์ ์ ์ธํ ํ์ ์์ต๋๋ค. ์ ๋ค๋ฆญ์ ๋ช
์์ ์ธ ์ ์ธ์ผ ๋ฟ์
๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋ฐํ๋ Provider๊ณผ useํ
์ ๋ณ์นญ์ ๋ถ์ฌํ์ฌ ๊ตฌ๋ถ์ด ์๋๊ฒ ํ๊ณ ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค.
๊ทธ๋ฆฌ๊ณ ํ
์์ ์ ๊ณตํ๋ ํจ์๋ ๋ฆฌ์กํธ์ useState ํ
์ setter ํจ์์ ๋์ผํ๊ฒ ๋์ํ๋ฏ๋ก ์ฌ์ฉํ๋ ๋ฐฉ์์ ๊ธ๋ฐฉ ์ตํ ์ ์์ต๋๋ค.
interface UserData {
name: string;
email: string;
preferences: {
theme: "light" | "dark";
notifications: boolean;
};
}
export const {
Provider: UserQueryProvider,
useContextQuery: useUserQuery,ํน
updateState: updateUserState,
setState: setUserState,
} = createContextQuery<UserData>({
name: "",
email: "",
preferences: {
theme: "light",
notifications: true,
},
});
function UserProfilePage({ userId }: { userId: string }) {
useEffect(() => {
// Initialize state with external data
const loadUserData = async () => {
const userData = await fetchUserData(userId);
updateUserState(userData); // Update entire state with fetched data
};
loadUserData();
}, [userId]);
return (
<UserQueryProvider>
<div className="user-profile">
<UserInfoForm />
<UserPreferencesForm />
<SaveButton />
</div>
</UserQueryProvider>
);
}
function UserInfoForm() {
// Subscribe to user info fields only
const [state, setState] = useUserQuery(["name", "email"]);
return (
<div className="user-info">
<h3>Basic Information</h3>
<div>
<label>Name:</label>
<input
value={state.name}
onChange={(e) =>
setState((prev) => ({ ...prev, name: e.target.value }))
}
/>
</div>
<div>
<label>Email:</label>
<input
value={state.email}
onChange={(e) =>
setState((prev) => ({ ...prev, email: e.target.value }))
}
/>
</div>
</div>
);
}
๋ชจ๋ ์ํ๋ฅผ Context Query๋ก ๊ด๋ฆฌํ๋ ๊ฒ์ ๋ง์ง ์์ต๋๋ค. ์ ์ ํ๊ฒ ๋ชฉ์ ์ ๋ฐ๋ผ ์ํ ๊ด๋ฆฌ ๋ฐฉ๋ฒ์ ์ ํํด์ผ ํฉ๋๋ค.
๊ทธ๋ผ Context Query๊ฐ ๊ฐ์ฅ ์ ํฉํ ์๊ธฐ๋ ์ธ์ ์ผ๊น์?
๋ฐ๋ก Props Drilling ์์ด ์ฌ๋ฌ ์ปดํฌ๋ํธ๋ก ์กฐํฉ๋ ํ๋์ ๊ธฐ๋ฅ์ ๊ตฌํํ ๋์ ์ ํฉํฉ๋๋ค. ์ ์ญ ์ํ๋ ๋ฆฌ์กํธ ์ฟผ๋ฆฌ๋ก ๊ด๋ฆฌํ๋ฉด ์ค๋ฒ ์์ง๋์ด๋ง์ด๊ณ
Context API๋ ์ ์ฒด ์ปดํฌ๋ํธ ํธ๋ฆฌ์๋ ์ ํฉํ๋ ์์ ์ปดํฌ๋ํธ ํธ๋ฆฌ๋ฅผ ์ํด์๋ ์ ํฉํ์ง ์๊ธฐ ๋๋ฌธ์
๋๋ค.
๊ทธ๋ฆฌ๊ณ Context API๋ ์์ฑํ๊ธฐ์ํด ์ง์ ํ
๊ณผ Provider๋ฅผ ์์ฑํด์ผ ํ๊ธฐ ๋๋ฌธ์ ์ฝ๋๊ฐ ๋ง์์ง๋๋ค.
๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ์๊ฒ, Props Drilling ์์ด ์ํ๋ฅผ ๊ณต์ ํ๋ ๋ชฉ์ ์ผ๋ก ์ฌ์ฉํด์ผํฉ๋๋ค.
๊ธฐ์ ์ ์ธ ๋์ด๋๊ฐ ๋์ ๊ฒ์ ์๋๋๋ค. ๊ทธ๋ฌ๋ ๊ฐ ๋ฌธ์ ์ ๋ถ๋ชํ๋ ์์ด๋์ด๋ฅผ ์ด์ฉํด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๊ฒ์ด ์ค์ํ์ต๋๋ค.
๊ทธ๋ฆฌ๊ณ ๊ฐ๋ฐ์๊ฐ ์์ฝ๊ฒ ์ด์ฉํ๋๋ก ์ค๊ณํ๋๊ฒ ์ญ์ ์ฌ์ด ๊ณผ์ ์ ์๋์์ต๋๋ค.
๋ ๊ฐ์ ํด์ผ ํ ์ ์ ๋ง์ง๋ง ๋ฒ์ ์ด ์ฌ๋ผ๊ฐ๋ฉด์ ๋ง์ ์ด๋ค์๊ฒ ์ ์ฒ๋ผ ๋์ผํ ๋ฌธ์ ๋ฅผ ๋ง๋ฌ์๋ ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํตํด ์์ฝ๊ฒ ๊ฐ๋ฐ ํ ์ ์์ผ๋ฉด ์ข๊ฒ ์ต๋๋ค.
Github - https://github.com/load28/context-query