export const First = () => {
const [num, setNum] = useState(0);
return (
<>
<span>{num}</span>
<Second num={num} />
</>
);
};
const Second = (props) => {
return <Third num={props.num} />;
};
const Third = (props) => {
return <Fourth num={props.num} />;
};
const Fourth = (props) => {
return <span>{props.num}</span>;
};
๋ค์๊ณผ ๊ฐ์ ์ฝ๋๊ฐ ์๋ค. ์กฐ๊ธ ์ด์ํ์ง๋ง ์์๋ ฅ์ ๋ฐํํด์ ์ด์ ๋ถ์ฌ๋ณด์. num์ First์์ ๊ด๋ฆฌํ๊ณ , First์ Fourth์์ ์ฌ์ฉํ๋ค.
ํ์ง๋ง ์ธ๋ฐ์์ด num์ Second, Third์๋ ์ ๋ฌํด์ผํ๋ค. ์ปดํฌ๋ํธ ๊ณ์ธต์ด ๊ทธ๋ ๊ฒ ๋์ด์๊ธฐ ๋๋ฌธ์ด๋ค. ์ด๋ฌํ ํ์์ด props drilling์ด๋ค.
์ค์ง ์ ๋ฌ๋ง์ ์ํ props๋ค์ด ํ์ ์ปดํฌ๋ํธ๋ค์ ๋ค์ ์กด์ฌํ๋ค๋ฉด ์ฑ์ ๊ท๋ชจ๊ฐ ์ปค์ง์๋ก ์ข์ง ์์ ์ํฅ๋ ์ปค์ง ๊ฒ์ด๋ค.
์ปดํฌ๋ํธ ํฉ์ฑ์ ํตํด props drilling์ ํด๊ฒฐํ ์๋ ์๋ค. ์์ ์ฝ๋๋ฅผ ์ปดํฌ๋ํธ ํฉ์ฑ์ผ๋ก ํด๊ฒฐํ ํํ๋ ๋ค์๊ณผ ๊ฐ๋ค.
export const First = () => {
const [num, setNum] = useState(0);
return (
<>
<span>{num}</span>
<Second>
<Third>
<Fourth num={num} />
</Third>
</Second>
</>
);
};
const Second = (props) => {
return <>{props.children}</>;
};
const Third = (props) => {
return <>{props.children}</>;
};
const Fourth = (props) => {
return <span>{props.num}</span>;
};
์ ๋ฌ๋ง์ ์ํ props๋ ๋์ด์ ์๊ณ ์์ ์ปดํฌ๋ํธ์์ ๋ฐ๋ก ํ์ํ ์์ฑ์ ์ฃผ์ ์์ผ์คฌ๋ค.
์ปดํฌ๋ํธ ํฉ์ฑ์ผ๋ก๋ง ํด๊ฒฐํ ์ ์๋ค๋ฉด ๊ตณ์ด Context๋ฅผ ์ฌ์ฉํ์ง ์์๋ ๋๋ค.
ํ์ง๋ง ๋ก๊ทธ์ธ ์ฌ๋ถ, ํ์ฌ ํ ๋ง ๋ฑ ํ๋์ ์ปดํฌ๋ํธ ํธ๋ฆฌ๊ฐ ์๋ ๋ค์ํ ๊ณณ์์ ์ฌ์ฉํ๋ค๋ฉด context๋ฅผ ์ฌ์ฉํ๋ ๊ฒ ๋ ์ง๊ด์ ์ผ๋ก ์ฝ๋๊ฐ ๋ณด์ผ ์ ์๋ค.
const myContext = createContext();
const MyStore = (props) => {
const [info, setInfo] = useState({
name: "lee",
age: 27,
});
return (
<myContext.Provider
value={{
info,
onClick: () => {
setInfo((prev) => ({ ...prev, age: prev.age++ }));
},
}}
>
{props.children}
</myContext.Provider>
);
};
์ฐ์ ์ปจํ ์คํธ๋ฅผ ๋ง๋ค๊ณ ๊ทธ๊ฒ์ ๊ด๋ฆฌํ store ์ปดํฌ๋ํธ๋ฅผ ๋ง๋ค์๋ค. ๊ณ ์ ๋ context ๊ฐ์ด๋ผ๋ฉด ๋ฐ๋ก store๊ฐ ํ์์์ง๋ง, ๋ณ๋์ฑ์ด ์๋ ๊ฐ์ด๋ผ๊ณ ๊ฐ์ ํ๋ค.
const ContextConsumer = () => {
const context = useContext(myContext);
useEffect(() => {
console.log("ContextConsumer is rendered!");
});
return (
<div>
<h1>Hello my name is {context.info.name}</h1>
<h1>I'am {context.info.age} years old.</h1>
<button onClick={context.onClick}>Click Me!</button>
</div>
);
};
const ContextInner = () => {
useEffect(() => {
console.log("ContextInner is rendered!");
});
return (
<>
<span>inner</span>
<ContextConsumer />
</>
);
};
const ContextExample = () => {
return (
<MyStore>
<ContextInner />
</MyStore>
);
};
context๋ฅผ ์๋นํ๋ ๊ฑด ๋ค์๊ณผ ๊ฐ๋ค. MyStore์ children์ผ๋ก ์ปดํฌ๋ํธ๋ฅผ ๋๊ฒจ์ฃผ๊ณ ํ์ํ ์ปดํฌ๋ํธ์์ useContext ํ ์ ์ด์ฉํด context๋ฅผ ์ฌ์ฉํ๋ค.
์ด๋ ๋ฆฌ๋ ๋๋ง ๋ถ๋ถ์ ์ฃผ์ํด์ ๋ด์ผํ๋๋ฐ, ๋ฒํผ์ ํด๋ฆญํด context๋ฅผ ๋ฐ๊ฟ MyStore๊ฐ ๋ฆฌ๋ ๋๋ง์ด ๋ฐ์ํ์ง๋ง ContextInner ์ปดํฌ๋ํธ๋ ๋ฆฌ๋ ๋๋ง์ด ๋ฐ์ํ์ง ์๋๋ค.
Provider ํ์์์ context๋ฅผ ๊ตฌ๋ ํ๋ ๋ชจ๋ ์ปดํฌ๋ํธ๋ Provider์ value prop๊ฐ ๋ฐ๋ ๋๋ง๋ค ๋ค์ ๋ ๋๋ง ๋ฉ๋๋ค. Provider๋ก๋ถํฐ ํ์ consumer(.contextType์ useContext์ ํฌํจํ)๋ก์ ์ ํ๋ shouldComponentUpdate ๋ฉ์๋๊ฐ ์ ์ฉ๋์ง ์์ผ๋ฏ๋ก, ์์ ์ปดํฌ๋ํธ๊ฐ ์ ๋ฐ์ดํธ๋ฅผ ๊ฑด๋ ๋ฐ๋๋ผ๋ consumer๊ฐ ์ ๋ฐ์ดํธ๋ฉ๋๋ค.
๋ฆฌ์กํธ ๊ณต์๋ฌธ์์ ์จ์๋ ๊ฒ์ฒ๋ผ context๋ฅผ ๊ตฌ๋ ํ๋ ๋ชจ๋ ์ปดํฌ๋ํธ๋ value๊ฐ ๋ฐ๋ ๋๋ง๋ค ๋ฆฌ๋ ๋๋ง์ด ๋ฐ์ํ๋ค.
const yourContext = createContext();
const YourStore = (props) => {
const [job, setJob] = useState("unemployed");
return (
<yourContext.Provider value={job}>{props.children}</yourContext.Provider>
);
};
๋ค์๊ณผ ๊ฐ์ context๋ฅผ ํ๋ ์ถ๊ฐํ๋ค๊ณ ํด๋ณด์. ์ด๊ฒ์ Provider๋ก ์ ๊ณตํ๋ ค๋ฉด ์๋์ ๊ฐ์ด ํด์ผํ๋ค.
const ContextExample = () => {
return (
<YourStore>
<MyStore>
<ContextInner />
</MyStore>
</YourStore>
);
};
context๊ฐ ์ถ๊ฐ๋ ์๋ก ์ฝ๋๋ ์ ์ ๋ณด๊ธฐ ํ๋ค์ด์ง ๊ฒ์ด๋ค. ๋ฌผ๋ก ์กฐ๊ธ ๋ณด๊ธฐ ์ข๊ฒ ๋ง๋๋ ๊ธฐ๋ฒ๋ ์กด์ฌํ์ง๋ฉด ์ด ๊ธ์์๋ ๋ค๋ฃจ์ง ์๊ฒ ๋ค. ๊ด์ฌ์ด ์๋ค๋ฉด React context hell์ ๋ณด๊ธธ ๋ฐ๋๋ค.
์ด๊ฒ ๋ง๊ณ ๋ ๋ฌธ์ ๊ฐ ๋ ์๋ค.
const ContextExample = () => {
return (
<>
<YourStore>
<MyStore>
<ContextInner />
</MyStore>
</YourStore>
<ContextConsumer />
</>
);
};
๋ง์ฝ ContextConsumer์ ๋ค๋ฅธ ๊ณณ์์ ์ฌ์ฌ์ฉํ๋ ค๋ฉด ์๋ฌ๋ฅผ ๋ฐ์์ํจ๋ค. context์ ์ฌ์ฉ์ ์ฌ์ฌ์ฉ์ฑ์ ๋จ์ด๋จ๋ฆฐ๋ค๋ ๋จ์ ๋ ์๋ค.
๋ชจ๋ ๋๊ตฌ๊ฐ ๊ทธ๋ฐ ๊ฒ์ฒ๋ผ ํญ์ ์ํฉ์ ๋ง๋ ๋๊ตฌ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ ์ข๋ค.