๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
Frontend/React

[ ๋ฆฌ์•กํŠธ(React) ] Higher Order Component ์‚ฌ์šฉํ•˜๊ธฐ

by YWTechIT 2023. 4. 13.
728x90

๐Ÿ“ Higher Order Component ์‚ฌ์šฉํ•˜๊ธฐ

๋‚˜๋Š” ๊ณ ์ฐจ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ฆ๊ฒจ ์‚ฌ์šฉํ•˜์ง€ ์•Š์ง€๋งŒ, React๋กœ ์ž‘์—…์„ ํ•˜๋‹ค ๋ณด๋ฉด ํŠน์ • ์ƒํ™ฉ์—์„œ ๊ณ ์ฐจ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ ํ•ฉํ•œ ๊ฒฝ์šฐ๊ฐ€ ์ข…์ข… ์žˆ๋‹ค. (๋ฌผ๋ก  ๊ณ ์ฐจ ์ปดํฌ๋„ŒํŠธ ์ด์™ธ์—๋„ ํšจ์œจ์ ์ธ ์ ‘๊ทผ๋ฐฉ๋ฒ•์ด ์žˆ์ง€๋งŒ, ์—ฌ๊ธฐ์„œ๋Š” ๊ณ ์ฐจ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜์ž.)

 

id, name, title๊ฐ€ ๋‹ด๊ธด ๋ฆฌ์ŠคํŠธ ํƒ€์ž…์˜ values๋Š” ๊ณ ์ฐจํ•จ์ˆ˜์ธ map method๋ฅผ ํ†ตํ•ด ์ปดํฌ๋„ŒํŠธ(<Button />)๋ฅผ ํ•˜๋‚˜์”ฉ ๋ Œ๋”๋งํ•˜๊ณ  ์žˆ๋Š” ์ƒํ™ฉ์ด์—ˆ๋‹ค. ์—ฌ๊ธฐ์„œ <Button /> ์ปดํฌ๋„ŒํŠธ ๋‚ด๋ถ€์—๋Š” ๊ณตํ†ต์ ์œผ๋กœ useState๊ฐ€ ์ฃผ์ž… ๋˜์–ด์•ผํ•˜๋Š” ์ƒํ™ฉ์ด๋‹ค. ์—ฌ๊ธฐ์„œ ๋‚˜๋Š” HOC๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•ด๊ฒฐํ–ˆ๋‹ค.

 

๊ณ ์ฐจ ์ปดํฌ๋„ŒํŠธ๋Š” ์ปดํฌ๋„ŒํŠธ ๋กœ์ง์„ ์žฌ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ React์˜ ๊ณ ๊ธ‰ ๊ธฐ์ˆ ์ธ๋ฐ, ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ฐ€์ ธ์™€ ์ƒˆ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜์ด๋‹ค. ๋‚˜๋งŒ์˜ ๋ฐฉ์‹๋Œ€๋กœ ์กฐ๊ธˆ ๋ง๋ถ™์—ฌ์„œ ๋งํ•˜์ž๋ฉด ์ƒ์œ„๋‹จ๊ณ„์—์„œ ๋‚ด ๋งˆ์Œ๋Œ€๋กœ ๊ทœ์น™์„ ์„ ์–ธ(useState ์ฃผ์ž…)ํ•˜๊ณ , ํ•˜์œ„ render ๋‹จ๊ณ„์—์„œ๋Š” ๊ธฐ์กด์˜ ๊ทœ์น™(๋‚ด๊ฐ€ ๋ Œ๋”๋ง์„ ํ•˜๋ ค๊ณ  ํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ (<Button />))์„ ๋”ฐ๋ฅด๋„๋ก ํ•œ๋‹ค๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉด ์กฐ๊ธˆ ๋” ์‰ฝ๊ฒŒ ์™€๋‹ฟ์„ ๊ฒƒ์ด๋‹ค.

 

์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ์‚ดํŽด๋ณด๊ณ  HOC๋ฅผ ์–ด๋–ป๊ฒŒ ๊ตฌ์„ฑํ• ์ง€ ๋ง‰๋ง‰ํ•˜๋‹ค๋ฉด ์ด ๊ธ€์„ ํ†ตํ•ด ์กฐ๊ธˆ์ด๋‚˜๋งˆ ๋„์›€์ด ๋˜์—ˆ์œผ๋ฉด ์ข‹๊ฒ ๋‹ค. (๋” ํšจ์œจ์ ์ธ ์ ‘๊ทผ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค๋ฉด ๋Œ“๊ธ€๋กœ ์•Œ๋ ค์ฃผ์‹œ๋ฉด ๊ฐ์‚ฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค! ๐Ÿ™‡๐Ÿพ‍โ™‚๏ธ)

728x90
interface FooComponentProps {
  values: Value[]
}

interface Value {
  id: string
  name: string
  title: string
}

function FooComponent({ values }: FooComponentProps) {
  return (
    <>
      {values.map(({ id, name, title }) => {
        const Button = withIsOpened(RequestButton)

        return (
          <div key={id}>
            <Button id={id} name={name} title={title} />
          </div>
        )
      })}
    </>
  )
}

interface RequestButtonProps {
  id: string
  name: string
  title: string
}

interface IsOpenedProps {
  isOpened: boolean
  setIsOpened: Dispatch<SetStateAction<boolean>>
}

function withIsOpened(
  WrappedComponent: ComponentType<RequestButtonProps & IsOpenedProps>,
) {
  return function WrappedWithIsOpened(props: RequestButtonProps) {
    const [isOpened, setIsOpened] = useState(false)

    return (
      <WrappedComponent
        isOpened={isOpened}
        setIsOpened={setIsOpened}
        {...props}
      />
    )
  }
}

function RequestButton({
  id,
  name,
  title,
  isOpened,
  setIsOpened,
}: RequestButtonProps & IsOpenedProps) {
  return <div>์ด๊ณณ์€ RequestButton์ž…๋‹ˆ๋‹ค.</div>
}

Reference

๋ฐ˜์‘ํ˜•

๋Œ“๊ธ€