DRY(Don’t Repeat Your Code) 한 코드를 짜기 위해 사용된다.
사용패턴에 대한 자세한 내용은 아래 블로그에 작성되어있다.
나의 경우에는 다음과 같이 컴포넌트 내에서 분기문(if/else
등)을 통해 처리하는게 많아서,
이러한 분기문을 HOC로 만들어 처리하여 깔끔하게 사용 하려했다.
// AsideMenuItem.svelte
{#if icon === MdDeveloperBoard}
<MdDeveloperBoard/>
{:else if icon === FaCommentDots}
<div class="relative">
<FaCommentDots/>
<div class="absolute -top-1 -right-1.5 flex justify-center items-center w-3.5 h-3.5 bg-orange-400 rounded-full text-black text-sm">3</div>
</div>
{:else if icon === FaComments}
<FaComments />
{:else if icon === TiChartArea}
<TiChartArea/>
{:else if icon === FaBookOpen}
<FaBookOpen/>
{:else if icon === DiTrello}
<DiTrello />
{/if}
힌트를 찾은 곳
Untangling Composition and Higher Order Components in Svelte
<svelte:component this:{어쩌구}>
공식문서를 살펴보면 다음과 같이 나와있다.
A component can change its category altogether with
<svelte:component>
instead of a sequence ofif
blocks...if block을 연속으로 사용하는 것 대신에
<svelte:component>
를 사용하라고 되어있다.
{#if selected.color === 'red'}
<RedThing/>
{:else if selected.color === 'green'}
<GreenThing/>
{:else if selected.color === 'blue'}
<BlueThing/>
{/if}
대신에
<svelte:component this={selected.component}/>
여기서 값을 전달해주는 this 는 어떠한 component constructor 가 될 수도 있고 falsy value 가 될 수도 있다.
위 그림 처럼 바로 class 가 string이 되어 출력되었다.
코드는 아래와 같이 받아온 icon 을 그대로 넣었었다.
어쩌구저쩌구
{icon}
저쩌구어쩌구
// AsideMenuItem.svelte
<svelte:component this={icon} />
처음에는 이렇게 단순하게 정리 하였다.
하지만 기존 코드를 보면, FaCommentDots
에는 추가적으로 처리해줘야 하는 UI 적인 요소가 있다.
그래서 새로운 Icon.svelte
파일을 만들고 slot
을 사용하여 다음과 같이 수정하였다.
// Icon.svelte
<script lang="ts">
export let icon;
</script>
<div>
<slot />
<svelte:component this={icon} />
<!-- 컴포넌트가 변수화 되면 svelte:component 를 사용 할 것 -->
</div>
// AsideMenuItem.svelte
{#if icon === FaCommentDots}
<Icon {icon}>
<div class="relative">
<div class="absolute -top-1 -right-1.5 flex justify-center items-center w-3.5 h-3.5 bg-orange-400 rounded-full text-black text-sm">3</div>
</div>
</Icon>
{:else}
<Icon {icon} />
{/if}
위 링크(AsideMenuItem.svelte
, Icon.svelte
)에서 HOC개념을 사용하여 리팩토링 한 내용을 볼 수 있다.