svelte:component

YunKuk Park·2022년 2월 4일
0

svelte

목록 보기
4/5

HOC 란?

  • Component 를 Argument 로 받아서 새로운 Component 를 리턴하는 함수이다.

HOC 사용 패턴

DRY(Don’t Repeat Your Code) 한 코드를 짜기 위해 사용된다.

사용패턴에 대한 자세한 내용은 아래 블로그에 작성되어있다.

react HOC란?

나의 경우에는 다음과 같이 컴포넌트 내에서 분기문(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}

그럼 Svelte 에서 어떻게 구현할까?

힌트를 찾은 곳
Untangling Composition and Higher Order Components in Svelte

<svelte:component this:{어쩌구}>

Svelte tutorial

공식문서를 살펴보면 다음과 같이 나와있다.

A component can change its category altogether with <svelte:component>
instead of a sequence of if 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}

리팩토링 Commit

위 링크(AsideMenuItem.svelte, Icon.svelte)에서 HOC개념을 사용하여 리팩토링 한 내용을 볼 수 있다.

profile
( • .̮ •)◞⸒⸒

0개의 댓글