[웹 컴포넌트] 기존 앱 전환 구현 - Children

Chad Lee·2023년 2월 28일
1
post-thumbnail

들어가며

: 웹 컴포넌트에서 자식 컴포넌트를 가지는 경우 부모 컴포넌트는 어떻게 구현해야 할까?
일단 먼저 아래와 같은 구조를 가진 HTML이 있다고 하자.

<drawing-canvas></drawing-canvas>
<tool-container>
  <color-button color='red'></color-button>
  <color-button color='blue' ></color-button>
  <color-button color='green' ></color-button>
  <color-button color='yellow' ></color-button>
</tool-container>

: 앞 포스팅에서 color-button 컴포넌트를 제작 하여 나열 하는것 까지 진행 했다.
여기서 drawing-canvas 컴포넌트를 구현하고 그 canvas에 선을 그릴 도구 모음을 하나의 컨테이너에 담는 구조로 만드는 것이 좋아 보인다. tool-container 컴포넌트를 만들고 자식으로 도구 컴포넌트들을 배치하면 간단히 해결 될까?
그렇지 않다.
만약에 별도 처리가 없다면 어떻게 될까?

위 그림 처럼 tool-container의 자식으로 보이기는 한다.
해당 자식들은 Light DOM으로 사용 되어 shadow-root에 붙지 않아 화면상에 보이지 않게 된다.

우리가 React로 제작한 컴포넌트만 보더라도 children을 다루기 위해서 아래처럼 별도 처리를 해준다.

//부모 컴포넌트
<Components>
  <ChildComponents />
</Components>
 
function Components({children}) {
  return (
  	<div>
    	{children}
    </div>
  )
}

이외 에도 다양 한 방법으로 자식을 표현 할 수 있다.

웹 컴포넌트도 마찬가지다.

1. DOM API 호출 하여 처리

: 아래 처럼 connectecdCallback에서 부모에 생성한 웹 컴포넌트를 붙이는 방법이 있다.

export default class ToolContainer extends Component {
  constructor() {
    super(tpl, styles);
  }

  connectedCallback() {
    const child = document.createElement("color-button");
    this.shadowRoot.appendChild(child.cloneNode(true));
  }
}

이 경우 attribute 설정이나 또 다른 자식 관계 설정을 별도 DOM API를 호출 해야 하는 번거로움이 있으므로 아래와 같이 해도 좋다.

    connectedCallback() {
    const child = `<color-button color='red'></color-button>`;
    this.shadowRoot.innerHTML = child;
  }

이렇게 해결 할 수도 있지만 부모 컴포넌트에서 자식을 특정하여 생성하고 붙이는 방법으로 별도의 코드가 들어가는 점은 그 다지 좋아 보이지 않는다. 물론 자식 관련 인수를 넘겨 받아 처리 할 수도 있지만 이럴 경우 부모 컴포넌트의 재사용성이 보장 되지 않는다. 다른 방법을 찾아 보자.

2. Slot 이용

: 앞 포스팅에서 알아봤던 slot 을 이용해보자.

const styles = `<style>.tools {
  display: flex;
  justify-content: center;
  flex-direction: row;
  margin-top: 15px;
}</style>`;
const tpl = `<div class='tools'><slot name='tool'></slot></div>`;

export default class ToolContainer extends Component {
  constructor() {
    super(tpl, styles);
  }
}

// 사용시
<tool-container>
  <color-button slot='tool' color='red'></color-button>
  <color-button slot='tool' color='blue' ></color-button>
  <color-button slot='tool' color='green' ></color-button>
  <color-button slot='tool' color='yellow' ></color-button>
</tool-container>

자식 표현을 위한 별도 코드 없이 표현 가능해졌다. inspector에서 확인해보면..

자식으로 선언했던 color-button이 모두 부모 컴포넌트의 slot 내부에 포함 되었다.

사실 slot을 사용한다면 자식 으로 넣지 않아도 해당 slot에 컴포넌트가 표현 되지만 관계를 잘 보이는데 도움이 되기 위해 이렇게 표현하는것은 괜찮은 방법 같다.

마치며

: 웹 컴포넌트에서 자식을 표현하는데 DOM API를 이용하는 방법과 slot을 이용하는 방법 두 가지를 비교해 보았을때 slot을 이용하면 재사용성과 좀 더 선언적으로 코드를 만드는데 도움을 되는것 같다. 하지만 여기서 동적으로 부모의 자식이 추가되는 구현이 필요하다면 DOM API를 이용해 추가 하는 로직이 필요해 보이긴 하다.

0개의 댓글