useContext()
1. ๊ฐ์
useContext()ํ
์ ๋ํด ์ดํดํ๊ธฐ ์ํด์๋ React์์์ Context๊ฐ ๋ฌด์์ธ์ง ์์์ผ ํ๋ค.
Context์ ๋ํด ๊ฐ๋จํ ์ดํด๋ณด๊ณ useContext()์ ์ฌ์ฉ๊ณผ ํน์ง์ ๋ํด ์์๋ณด์.
2. Context
์ผ๋ฐ์ ์ธ React ์ ํ๋ฆฌ์ผ์ด์ ์์ ๋ฐ์ดํฐ๋ ์์์ ์๋๋ก (์ฆ, ๋ถ๋ชจ๋ก๋ถํฐ ์์์๊ฒ) props๋ฅผ ํตํด ์ ๋ ๋์ง๋ง, ์ ํ๋ฆฌ์ผ์ด์ ์์ ์ฌ๋ฌ ์ปดํฌ๋ํธ๋ค์ ์ ํด์ค์ผ ํ๋ props์ ๊ฒฝ์ฐ ์ด ๊ณผ์ ์ด ๋ฒ๊ฑฐ๋ก์ธ ์ ์์ต๋๋ค. context๋ฅผ ์ด์ฉํ๋ฉด, ํธ๋ฆฌ ๋จ๊ณ๋ง๋ค ๋ช ์์ ์ผ๋ก props๋ฅผ ๋๊ฒจ์ฃผ์ง ์์๋ ๋ง์ ์ปดํฌ๋ํธ๊ฐ ์ด๋ฌํ ๊ฐ์ ๊ณต์ ํ๋๋ก ํ ์ ์์ต๋๋ค.
์๋ ๋ฆฌ์กํธ ๊ณต์๋ฌธ์์ ๋ํ๋ Context์ ๋ํ ์ค๋ช
์ด๋ค.
์ฆ, ๊ฐ์ props๋ฅผ ์์ ์ปดํฌ๋ํธ์๊ฒ ๋ง์ด ์ ๋ฌํ์ฌ ๋ง์ ์ปดํฌ๋ํธ๊ฐ ๊ณต์ ํ๊ณ ์๋จ๋ฉด Context๋ฅผ ์ฌ์ฉํ์ฌ ์ ๋ฌํ๋ ๊ณผ์ ์ ์๋ตํ๊ณ ๋ถ๋ชจ ์ปดํฌ๋ํธ์์ ํ ๋ฒ ์ ์ญ์ผ๋ก ์ ๋ฌํ์ฌ ๋ฐ์ดํฐ๋ฅผ ๊ณต์ ํ ์ ์๋ค.
2-1. Context API - React.createContext
const MyContext = React.createContext(defaultValue);Context ๊ฐ์ฒด๋ฅผ ๋ง๋๋ API์ด๋ค. Context ๊ฐ์ฒด๋ฅผ ๊ตฌ๋
ํ๊ณ ์๋ ์ปดํฌ๋ํธ๋ฅผ ๋ ๋๋งํ ๋ React๋ ํธ๋ฆฌ ์์์์ ๊ฐ์ฅ ๊ฐ๊น์ด ์๋ ์ง์ด ๋ง๋ Provider๋ก๋ถํฐ ํ์ฌ๊ฐ์ ์ฝ๋๋ค.
2-2. Context API - Context.Provider
<MyContext.Provider value={/* ์ด๋ค ๊ฐ */}>Context ์ค๋ธ์ ํธ์ ํฌํจ๋ React ์ปดํฌ๋ํธ์ธ Provider๋ context๋ฅผ ๊ตฌ๋
ํ๋ ์ปดํฌ๋ํธ๋ค์๊ฒ context์ ๋ณํ๋ฅผ ์๋ฆฌ๋ ์ญํ ์ ํ๋ค.
Provider ์ปดํฌ๋ํธ๋ value props์ ๋ฐ์์ ์ด ๊ฐ์ ํ์์ ์๋ ์ปดํฌ๋ํธ์๊ฒ ์ ๋ฌํ๋ค. ๊ฐ์ ์ ๋ฌ๋ฐ์ ์ ์๋ ์ปดํฌ๋ํธ์ ์์ ์ ํ์ ์๋ค. ๋ง์ฝ Provider ์ปดํฌ๋ํธ ํ์์ ๋ ๋ค๋ฅธ Provider ์ปดํฌ๋ํธ๊ฐ ์๋ ๊ฒฝ์ฐ ํ์ Provider์ ๊ฐ์ด ์ฐ์ ์ ๋๋ค.
Provider ์ปดํฌ๋ํธ์ value props๊ฐ ๋ฐ๋ ๋ ๋ง๋ค ํด๋น Provider์ปดํฌ๋ํธ๋ฅผ ๊ตฌ๋
ํ๊ณ ์๋ ์ปดํฌ๋ํธ๋ ๋ฆฌ๋ ๋๋ง ๋๋ค.
2-3. Context API - Context.Consumer
<MyContext.Consumer>
{value => /* context ๊ฐ์ ์ด์ฉํ ๋ ๋๋ง */}
</MyContext.Consumer>context ๋ณํ๋ฅผ ๊ตฌ๋
ํ๋ React ์ปดํฌ๋ํธ์ด๋ค. ์ด ์ปดํฌ๋ํธ๋ฅผ ์ฌ์ฉํ๋ฉด ํจ์ ์ปดํฌ๋ํธ์์์ context๋ฅผ ๊ตฌ๋
ํ ์ ์๋ค.
Context.Consumer ์ปดํฌ๋ํธ์ ์์์ ํจ์์ฌ์ผ ํ๋ค. ์ด ํจ์๋ context์ ํ์ฌ๊ฐ์ ๋ฐ๊ณ React๋
ธ๋๋ฅผ ๋ฐํํ๋ค. ์ด ํจ์๊ฐ ๋ฐ๋ value ๋งค๊ฐ๋ณ์ ๊ฐ์ ํด๋น context์ Provider ์ปดํฌ๋ํธ ์ค ์์ ํธ๋ฆฌ์์ ๊ฐ์ฅ ๊ฐ๊น์ด Provider ์ปดํฌ๋ํธ์ value props๊ณผ ๋์ผํ๋ค.
3. Context๋ฅผ ์ฌ์ฉํ ์ ์ฃผ๋ ๊ธฐ๋
ํ ์ปดํฌ๋ํธ
์ ์ฃผ๋ ์ฌํ ๊ธฐ๋
ํ ๋ชฉ๋ก์ ๋ง๋๋ ์ปดํฌ๋ํธ๋ฅผ Context๋ฅผ ํ์ฉํ์ฌ ์๋กญ๊ฒ ์์ฑํด๋ณด์.
//App.js
import { useState, createContext } from "react";
import Children from "./Children";
// 1) createContext๋ฅผ ์ฌ์ฉํ์ฌ Context ๊ฐ์ฒด ๋ง๋ค๊ธฐ
export const AppContext = createContext({
gift: ["ํ๋ผ๋ด", "์ด์ฝ๋ฆฟ"],
addGift: () => {},
});
function App() {
const [gift, setGift] = useState(["ํ๋ผ๋ด", "์ด์ฝ๋ฆฟ"]);
const addGift = (gift) => {
setGift((prev) => [...prev, gift]);
};
return (
// 2) AppContext.Provider ์์ฑํ์ฌ Context์ ๋ณํ ์๋ฆฌ๊ธฐ
<AppContext.Provider value={{ gift, addGift }}>
<div>์๋
, ์ ์ฃผ!</div>
<Children />
</AppContext.Provider>
);
}
export default App;
// Children.js
import React from "react";
import { useForm } from "react-hook-form";
import { AppContext } from "./App";
const Children = () => {
const { register, handleSubmit, setValue, getValues } = useForm();
return (
// 3) AppContext.Consumer๋ฅผ ํตํด Context๋ฅผ ๊ตฌ๋
ํ๊ธฐ
<AppContext.Consumer>
{({ gift, addGift }) => (
<div>
<form
onSubmit={handleSubmit(() => {
console.log(`${gift}๊ฐ ๊ธฐ๋
ํ ๋ชฉ๋ก์ ์ถ๊ฐ๋ฉ๋๋ค๐`);
addGift(getValues("gift"));
setValue("gift", "");
})}
>
<input {...register("gift")} placeholder="์ฌ๊ณ ์ถ์ ๊ธฐ๋
ํ" />
<input type="submit" value="๊ธฐ๋
ํ ๊ณ ๋ฅด๊ธฐ" />
</form>
<div>๋์ ๊ธฐ๋
ํ ๋ชฉ๋ก: {gift.join(", ")}</div>
</div>
)}
</AppContext.Consumer>
);
};
export default Children;
1) createContext๋ฅผ ์ฌ์ฉํ์ฌ Context ๊ฐ์ฒด ๋ง๋ค๊ธฐ
export const AppContext = createContext({
gift: ["ํ๋ผ๋ด", "์ด์ฝ๋ฆฟ"],
addGift: () => {},
});createcontext API๋ฅผ ์ฌ์ฉํ์ฌ Context ๊ฐ์ฒด๋ฅผ ๋ง๋ค๋ค. defaultValue๋ก๋ ํ์ ์ปดํฌ๋ํธ๊ฐ ๋ฐ๊ณ ์๋ ๋งค๊ฐ๋ณ์(Provider API์ value) ๋ชจ์๊ณผ ๋์ผํ๊ฒ ๋ง๋ค์๋ค.
2) AppContext.Provider ์์ฑํ์ฌ Context์ ๋ณํ ์๋ฆฌ๊ธฐ
<AppContext.Provider value={{ gift, addGift }}>
<div>์๋
, ์ ์ฃผ!</div>
<Children />
</AppContext.Provider>gift๋ App์ปดํฌ๋ํธ์์ ๋ง๋ state๊ฐ์ด๊ณ addGiftํจ์๋ gift์ ๊ฐ์ ๋ณํ์ํค๊ธฐ ์ํด ์ฌ์ฉ๋๋ ํจ์์ด๋ค. ์ด๋ฅผ Proivder API์ value๋ฅผ ํตํด ์์ ์ปดํฌ๋ํธ๊ฐ ํด๋น ๊ฐ๋ค์ ๊ตฌ๋
ํ ์ ์๋๋ก ํ๋ค.
์ฒ์์ ์ค๋ฅ๊ฐ ๋ฌ๋ ๋ถ๋ถ์ด๋ค.
value props์ ๊ฐ์ด Object์ด๋ฉดAppContext.Consumer์ปดํฌ๋ํธ์์ Object๋ก ๋ฐ๊ณ Array์ด๋ฉดAppContext.Consumer์ปดํฌ๋ํธ์์ Array๋ก ๋ฐ์
3) AppContext.Consumer๋ฅผ ํตํด Context๋ฅผ ๊ตฌ๋
ํ๊ธฐ
<AppContext.Consumer>
{({ gift, addGift }) => ()}
</AppContext.Consumer>consumer API๋ฅผ ํตํด AppContext.Consumer์ปดํฌ๋ํธ๋ฅผ ๋ง๋ค์๋ค. ํด๋น ์ปดํฌ๋ํธ์ ์์์ ํจ์๋ก ์ธ์๋ก AppContext.Consumer์ปดํฌ๋ํธ์์ ์ ๋ฌํ value props์ด ๋ค์ด์๋ค. ์ด๋ฅผ ๊ฐ์ง๊ณ ํ๋ฉด์ ๊ทธ๋ฆฌ๋ฉด ๋๋ค.
ํ์คํ
props๊ฐ ํ์์๋ ์ปดํฌ๋ํธ๋ค์๊ฒ ๊น์งprops๋ฅผ ์ ๋ฌํ๋ ๊ฒ ๋ณด๋คContext๋ฅผ ์ฌ์ฉํ์ฌ ๋ฑ ํ์ํ ์์ ์ปดํฌ๋ํธ์๊ฒ๋ง ์ ๋ฌํ๋ ๊ฒ์ด ๊น๋ํด ๋ณด์ธ๋ค. ์ด์ ์๋์์Context๋ฅผ ๋ ํธํ๊ฒ ์ฌ์ฉํ ์ ์๊ฒ ํด์ฃผ๋useContext()ํ ์ ๋ํด ์ดํด๋ณด์.
4. useContext()ํ
์ฌ์ฉํ๊ธฐ
useContext()์ ๊ธฐ๋ณธ ์ฌ์ฉ๋ฒ์ ์๋์ ๊ฐ๋ค.
const value = useContext(MyContext);context ๊ฐ์ฒด(React.createContext์์ ๋ฐํ๋ ๊ฐ)์ ๋ฐ์ ๊ทธ context์ ํ์ฌ ๊ฐ์ ๋ฐํํ๋ค. context์ ํ์ฌ ๊ฐ์ ํธ๋ฆฌ ์์์ ์ด Hook๋ฅผ ํธ์ถํ๋ ์ปดํฌ๋ํธ ๊ฐ์ฅ ๊ฐ๊น์ด์ ์๋ <MyContext.Provider>์ value props์ ์ํด ๊ฒฐ์ ๋๋ค.
useContext()ํ
์ ํธ์ถํ ์ปดํฌ๋ํธ๋ context๊ฐ์ด ๋ณ๊ฒฝ๋๋ฉด ํญ์ ๋ฆฌ๋ ๋๋ง ๋๋ค.
์ด์ useContext()ํ
์ ์ฌ์ฉํ์ฌ ์์ Children.js ์ปดํฌ๋ํธ๋ฅผ ์๋์ ๊ฐ์ด ์์ ํ์.
// Children.js
import React, { useContext } from "react";
import { useForm } from "react-hook-form";
import { AppContext } from "./App";
const Children = () => {
const { gift, addGift } = useContext(AppContext);
const { register, handleSubmit, setValue, getValues } = useForm();
return (
<div>
<form
onSubmit={handleSubmit(() => {
console.log(`${getValues("gift")}๊ฐ ๊ธฐ๋
ํ ๋ชฉ๋ก์ ์ถ๊ฐ๋ฉ๋๋ค๐`);
addGift(getValues("gift"));
setValue("gift", "");
})}
>
<input {...register("gift")} placeholder="์ฌ๊ณ ์ถ์ ๊ธฐ๋
ํ" />
<input type="submit" value="๊ธฐ๋
ํ ๊ณ ๋ฅด๊ธฐ" />
</form>
<div>๋์ ๊ธฐ๋
ํ ๋ชฉ๋ก: {gift.join(", ")}</div>
</div>
);
};
export default Children;<AppContext.Consumer>์ปดํฌ๋ํธ๊ฐ ์์ด์ง ๊ฒ์ ํ์ธํ ์ ์๋ค. ๋์ ์ useContext()ํ
์ ํตํด gift์ addGift๋ฅผ ๋ถ๋ฌ์ AppContext์ ๊ฐ์ ์ฌ์ฉํ๊ณ ์๋ค.
useContext()ํ
์ ์ฌ์ฉํจ์ผ๋ก์จ ์ด์ ๋ณด๋ค ๊ฐ๊ฒฐํ ์ฝ๋ ์์ฑ์ด ๊ฐ๋ฅํด์ก๋ค.
5. Conclusion
useContext()ํ ๋useReducer()ํ ๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก ํ ๋ฒ๋ ์ฌ์ฉํด๋ณธ ์ ์ด ์๋ React Hook์ด์๋ค. ๊ทธ๋์ ์ฒ์์๋ ์์ํ์์ง๋ง ์๊ฐ๋ณด๋ค ๊ทธ๋ฆฌ? ์ด๋ ต๊ณ ๋ณต์กํ ๊ฐ๋ ์ด ์๋์๊ธฐ ๋๋ฌธ์ ๊ธ๋ฐฉ ์ดํด๊ฐ ๊ฐ๋ฅํ๋ค. ๊ถ๊ธํ ์ ์useContext()ํ ๊ณผuseReducer()ํ ์ดporps๋ฅผ ํ์ํ์ง ์๋ ์์ ์ปดํฌ๋ํธ๋ฅผ ๊ฑด๋ ๋ฐ๊ณ ํ์ํ ์์ ์ปดํฌ๋ํธ์๊ฒ๋งprops๋ฅผ ์ ๋ฌ์ ๊ฐ๋ฅํ๊ฒ ํ๋ ํ ์ผ๋ก ๋ณด์ธ๋ค. ๊ทธ๋ ๋ค๋ฉด ์ด ๋๊ฐ์ง์ ํ ์ ๋ชจ๋ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์์ง ์๋๋ฉด ์ํฉ์ ๋ฐ๋ผ ํ ๊ฐ์ง๋ฅผ ์ ํํ์ฌ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์์ง๊ฐ ๊ถ๊ธํ๋ค.
๋ง๋ฌด๋ฆฌ๋ก useContext()ํ
๊ณผ useReducer()ํ
์ ๋ชจ๋ ์ฌ์ฉํ์ฌ ์์ ์ปดํฌ๋ํธ๋ฅผ ์์ฑํ์๋ค. ํ์คํ ์ปดํฌ๋ํธ์ ๊ตฌ์กฐ๊ฐ ๋ณต์กํด์ง๋ค๋ฉด ์ด ํ
๋ค์ ์ ์ฉํด์ง ๊ฒ ๊ฐ๋ค๐ ๊ทธ๋ฆฌ๊ณ ๊ฐ์ ๋ด์ฉ์ด์ง๋ง ์ฝ๋์ ์ฌ์ฉ๋ ํ
์ด ๋ค๋ฅด๋ค๋ ๊ฒ๋ ์ฌ๋ฐ๋ ๋ถ๋ถ์ด๋ค.(์ฌ์ค ์ด๊ฑด ๊ทธ๋ฅ useState๋ง ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์๊ฑฐ ๊ฐ๋ค๐)
// App.js
import { createContext, useReducer } from "react";
import Children from "./Children";
const inItGift = ["ํ๋ผ๋ด", "์ด์ฝ๋ฆฟ"];
const reducer = (gift, action) => {
switch (action.type) {
case "submitGift":
return [...gift, action.gift];
default:
throw new Error("type Error");
}
};
export const AppContext = createContext({
inItGift,
dispatch: () => {},
});
function App() {
const [gift, dispatch] = useReducer(reducer, inItGift);
return (
<AppContext.Provider value={{ gift, dispatch }}>
<div>์๋
, ์ ์ฃผ!</div>
<Children />
</AppContext.Provider>
);
}
export default App;
// Children.js
import React, { useContext } from "react";
import { useForm } from "react-hook-form";
import { AppContext } from "./App";
const Children = () => {
const { gift, dispatch } = useContext(AppContext);
const { register, handleSubmit, setValue } = useForm();
const onSubmitFrom = (data) => {
const { gift } = data;
console.log(`${gift}๊ฐ ๊ธฐ๋
ํ ๋ชฉ๋ก์ ์ถ๊ฐ๋ฉ๋๋ค๐`);
dispatch({
type: "submitGift",
gift,
});
setValue("gift", "");
};
return (
<div>
<form onSubmit={handleSubmit(onSubmitFrom)}>
<input {...register("gift")} placeholder="์ฌ๊ณ ์ถ์ ๊ธฐ๋
ํ" />
<input type="submit" value="๊ธฐ๋
ํ ๊ณ ๋ฅด๊ธฐ" />
</form>
<div>๋์ ๊ธฐ๋
ํ ๋ชฉ๋ก: {gift.join(", ")}</div>
</div>
);
};
export default Children;์ฐธ๊ณ
[TIL #6] React (Hooks) - useContext ๋? Context
๐ 2022-08-10
Last updated