๐Ÿš ๊ณ ์ฐจ ์ปดํฌ๋„ŒํŠธ ์‚ฌ์šฉํ•˜๊ธฐ

Lee Jooamยท2022๋…„ 6์›” 3์ผ
0

๐Ÿ™„ ๊ณ ์ฐจ ์ปดํฌ๋„ŒํŠธ(HOC)?

๊ณ ์ฐจ ์ปดํฌ๋„ŒํŠธ(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} />

๊ณ ์ฐจ ์ปดํฌ๋„ŒํŠธ์—์„œ ์œ„์™€ ๊ฐ™์€ ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ–ˆ๋‹ค. ์กฐ๊ธˆ ์ด์ƒํ•˜๋‹ค๊ณ  ๋Š๊ปด์ง„๋‹ค. ์ด๊ฒŒ ์–ด๋–ป๊ฒŒ ๊ฐ€๋Šฅํ•˜์ง€?

profile
ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœ์ž๋กœ ๊ฑธ์–ด๊ฐ€๋Š” ์ค‘์ž…๋‹ˆ๋‹ค.

0๊ฐœ์˜ ๋Œ“๊ธ€