๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
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

๋ฐ˜์‘ํ˜•

๋Œ“๊ธ€