๐ Higher Order Component ์ฌ์ฉํ๊ธฐ
๋๋ ๊ณ ์ฐจ ์ปดํฌ๋ํธ๋ฅผ ์ฆ๊ฒจ ์ฌ์ฉํ์ง ์์ง๋ง, React๋ก ์์ ์ ํ๋ค ๋ณด๋ฉด ํน์ ์ํฉ์์ ๊ณ ์ฐจ ์ปดํฌ๋ํธ๋ฅผ ์ฌ์ฉํ๋ฉด ์ ํฉํ ๊ฒฝ์ฐ๊ฐ ์ข ์ข ์๋ค. (๋ฌผ๋ก ๊ณ ์ฐจ ์ปดํฌ๋ํธ ์ด์ธ์๋ ํจ์จ์ ์ธ ์ ๊ทผ๋ฐฉ๋ฒ์ด ์์ง๋ง, ์ฌ๊ธฐ์๋ ๊ณ ์ฐจ ์ปดํฌ๋ํธ๋ฅผ ์ฌ์ฉํ๋ค๊ณ ๊ฐ์ ํ์.)
id, name, title
๊ฐ ๋ด๊ธด ๋ฆฌ์คํธ ํ์
์ values
๋ ๊ณ ์ฐจํจ์์ธ map
method๋ฅผ ํตํด ์ปดํฌ๋ํธ(<Button />
)๋ฅผ ํ๋์ฉ ๋ ๋๋งํ๊ณ ์๋ ์ํฉ์ด์๋ค. ์ฌ๊ธฐ์ <Button />
์ปดํฌ๋ํธ ๋ด๋ถ์๋ ๊ณตํต์ ์ผ๋ก useState
๊ฐ ์ฃผ์
๋์ด์ผํ๋ ์ํฉ์ด๋ค. ์ฌ๊ธฐ์ ๋๋ HOC๋ฅผ ์ฌ์ฉํ์ฌ ํด๊ฒฐํ๋ค.
๊ณ ์ฐจ ์ปดํฌ๋ํธ๋ ์ปดํฌ๋ํธ ๋ก์ง์ ์ฌ์ฌ์ฉํ๊ธฐ ์ํ React์ ๊ณ ๊ธ ๊ธฐ์ ์ธ๋ฐ, ์ปดํฌ๋ํธ๋ฅผ ๊ฐ์ ธ์ ์ ์ปดํฌ๋ํธ๋ฅผ ๋ฐํํ๋ ํจ์์ด๋ค. ๋๋ง์ ๋ฐฉ์๋๋ก ์กฐ๊ธ ๋ง๋ถ์ฌ์ ๋งํ์๋ฉด ์์๋จ๊ณ์์ ๋ด ๋ง์๋๋ก ๊ท์น์ ์ ์ธ(useState ์ฃผ์
)ํ๊ณ , ํ์ render ๋จ๊ณ์์๋ ๊ธฐ์กด์ ๊ท์น(๋ด๊ฐ ๋ ๋๋ง์ ํ๋ ค๊ณ ํ๋ ์ปดํฌ๋ํธ (<Button />
))์ ๋ฐ๋ฅด๋๋ก ํ๋ค๋ผ๊ณ ์๊ฐํ๋ฉด ์กฐ๊ธ ๋ ์ฝ๊ฒ ์๋ฟ์ ๊ฒ์ด๋ค.
์๋ ์ฝ๋๋ฅผ ์ดํด๋ณด๊ณ HOC๋ฅผ ์ด๋ป๊ฒ ๊ตฌ์ฑํ ์ง ๋ง๋งํ๋ค๋ฉด ์ด ๊ธ์ ํตํด ์กฐ๊ธ์ด๋๋ง ๋์์ด ๋์์ผ๋ฉด ์ข๊ฒ ๋ค. (๋ ํจ์จ์ ์ธ ์ ๊ทผ๋ฐฉ๋ฒ์ด ์๋ค๋ฉด ๋๊ธ๋ก ์๋ ค์ฃผ์๋ฉด ๊ฐ์ฌํ๊ฒ ์ต๋๋ค! ๐๐พโ๏ธ)
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>
}
๋๊ธ