๊ณ ์ฐจ ์ปดํฌ๋ํธ(HOC, Higher Order Component)๋ ์ปดํฌ๋ํธ ๋ก์ง์ ์ฌ์ฌ์ฉํ๊ธฐ ์ํ React์ ๊ณ ๊ธ ๊ธฐ์ ์ ๋๋ค. ๊ณ ์ฐจ ์ปดํฌ๋ํธ(HOC)๋ React API์ ์ผ๋ถ๊ฐ ์๋๋ฉฐ, React์ ๊ตฌ์ฑ์ ํน์ฑ์์ ๋์ค๋ ํจํด์ ๋๋ค.
๊ณ ์ฐจ ์ปดํฌ๋ํธ(Higher Order Component)๋ ์ปดํฌ๋ํธ๋ฅผ ๋ฐํํ๋ 'ํจ์'์ด๋ค. ์ปดํฌ๋ํธ๋ฅผ ์ธ์๋ก ๋ฐ์ ๊ทธ๊ฒ์ ๋ฐํํ๊ธฐ๋ ํ๋ค.
๊ณ ์ฐจ ์ปดํฌ๋ํธ๋ฅผ ์ฌ์ฉํ๋ ๊ธฐ๋ณธ์ ์ธ ์ด์ ๋ ์ถ์ํ์ด๋ค. ํน์ ๊ธฐ๋ฅ์ด ์ฌ๋ฌ ์ปดํฌ๋ํธ์ ์ค๋ณต๋์ด ๋ํ๋ ๊ฒฝ์ฐ ๊ทธ๊ฒ์ ๊ณ ์ฐจ ์ปดํฌ๋ํธ๋ก ํ๋ฒ wrappingํ๋ฉด ์ถ์ํ ๊ณ์ธต์ ์ ๊ณตํ ์ ์๋ค.
์๋ฅผ ๋ค์ด ์ ์ ๊ฐ ํ์ด์ง์ ์ ๊ทผํ ๋ ํด๋น ์ ์ ๊ฐ ๋ก๊ทธ์ธ ์ค์ธ์ง ์ฌ๋ถ, ํน์ ํน์ ๊ฒ์๊ธ์ด๋ ๋๊ธ์ ์์ฑ์์ธ์ง ํ์ธํ๋ ์์ ์ ํด๊ฒฐ์ฑ ์ค ํ๋๋ก ๊ณ ์ฐจ ์ปดํฌ๋ํธ๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
๋ง์ฝ ํน์ ์ปดํฌ๋ํธ์์ ์ ์ ์ ๊ถํ์ ํ์ธํ ํ์๊ฐ ์๋ค๋ฉด ๋ค์๊ณผ ๊ฐ์ด ๊ณ ์ฐจ ์ปดํฌ๋ํธ๋ฅผ ๊ตฌ์ฑํ ์ ์๋ค.
const Board = ({ permission, ...props }) => {
console.log(props);
return (
<div>
<span>Hello</span>
{permission && <button>delete</button>}
</div>
);
};
๋ค์๊ณผ ๊ฐ์ Board ์ปดํฌ๋ํธ๊ฐ ์๋ค๊ณ ํ ๋, ์ฐ๋ฆฌ๋ ํด๋น ์ปดํฌ๋ํธ๋ฅผ ๋ ๋๋งํ ๋๋ง๋ค Board์ ๋ํ ๊ถํ์ ์๊ณ ์ถ๋ค.
์ด๊ฒ์ ๊ณ ์ฐจ ์ปดํฌ๋ํธ๋ฅผ ์ด์ฉํด ๋ง๋ค๋ฉด ์๋์ ๊ฐ์ ๋ชจ์์ด ๋์ฌ ๊ฒ ๊ฐ๋ค.
const withCheckPermission = (TargetComponent) => {
return function WithCheckPermission(props) {
const [permission, setPermisson] = useState(null);
useEffect(() => {
async function checkPermisson() {
const result = await fetch("/api/checkPermisson").then((res) =>
res.json()
);
setPermisson(result);
}
checkPermisson();
}, []);
return <TargetComponent {...props} permission={permission} />;
};
};
export default withCheckPermission(Board);
์ปดํฌ๋ํธ๋ฅผ ์ธ์๋ก ๋ฐ๋ ํจ์๊ฐ ์ถ๊ฐ ์์ ์ ํ๋ ๋๋ค๋ฅธ ์ปดํฌ๋ํธ๋ฅผ ๋ฐํํ๊ณ ์๋ค. ์ด๊ฒ์ด ๊ณ ์ฐจ ์ปดํฌ๋ํธ์ด๋ค.
์๋ง ๋น๋๊ธฐ์ ์ธ ์์ ์ด ํ์ํ๋ค๋ฉด ์์ ๊ฐ์ ํํ๋ก ์์ ํ์ง ์์๊น ์์ํด๋ณธ๋ค.
function App() {
return <div className='App'><Board subTitle='Title' /></div>;
}
์ฌ์ฉ์ ๋ค์๊ณผ ๊ฐ์ด ์ผ๋ฐ ์ปดํฌ๋ํธ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ๊ณผ ๊ฐ๋ค.
๋ง์ฝ ๋ค์๊ณผ ๊ฐ์ ๊ฒฝ์ฐ๋ผ๋ฉด ์ด๋ป๊ฒ ํด์ผํ ๊น? ์ฐ๋ฆฌ๋ Board ์ปดํฌ๋ํธ๋ฅผ ๋ ๋๋งํ๊ณ ๊ทธ๊ฒ์ console์ ๊ธฐ๋กํ๊ณ ์ถ๋ค.
๋จ์ํ ํด๊ฒฐ์ฑ ์ WithCheckPermission์ console.log๋ฅผ ์ถ๊ฐํ๋ ๊ฒ์ด์ง๋ง ๊ณ ์ฐจ ์ปดํฌ๋ํธ๋ฅผ ์ด์ฉํด ํด๊ฒฐํด๋ณด์.
const withLogging = (TargetComponent) => {
return function WithLogging() {
console.log("Board is Mounted");
return <TargetComponent />;
};
};
export const WithLoggionBoard = withLogging(withCheckPermission(Board));
๊ณ ์ฐจ ์ปดํฌ๋ํธ์ TargetComponent์ ๋ค๋ฅธ ๊ณ ์ฐจ ์ปดํฌ๋ํธ๋ฅผ ์ธ์๋ก ๋ฃ๋๋ค๋ฉด ํด๊ฒฐํ ์ ์๋ค.
<Component {...props} />
๊ณ ์ฐจ ์ปดํฌ๋ํธ์์ ์์ ๊ฐ์ ๋ฌธ๋ฒ์ ์ฌ์ฉํ๋ค. ์กฐ๊ธ ์ด์ํ๋ค๊ณ ๋๊ปด์ง๋ค. ์ด๊ฒ ์ด๋ป๊ฒ ๊ฐ๋ฅํ์ง?