WebComponentsを使ってみよう(その2)

こんにちは。SaaS Product Divisionのとみたです。

WebComponentsを使ってみよう(その1)の続きです。 今回は、Reactアプリケーションをカスタムエレメントとし、さらに別のフレームワークから使う、といったマイクロフロントエンドをやっていく上で実践的な部分について記載します。

Reactでカスタムエレメントを作る

前回の記事では、ピュアなJavaScriptで実装する方法を書きましたが、では、Reactなどのフロントエンドフレームワークではどのように実装すればよいかを書いていこうと思います。

大抵は、ピュアなJavaScriptと同じです。

以下のようにすることでHelloWorldコンポーネントをカスタムエレメントとして描画できます。

const React = require("react");
const { render } = require("react-dom");
const HelloWorld = () => {
  return (
    <h1>Hello World</h1>
  );
}

class HelloWorldElement extends HTMLElement {
  constructor() {
    super();
    this.attachShadow({ mode: "open" });
  }

  connectedCallback() {
    render(<HelloWorld />, this.shadowRoot);
  }
}

customElement.define("hello-world", HelloWorldElement);

大事なのは、 HelloWorld コンポーネントを ReactDOMの render 関数で this.shadowRoot にマウントしているところです。

通常、Reactコンポーネントを表示する際は、 render(<Component />, document.body) と書いたりしますが、document.body の部分がカスタムエレメントが内包しているShadowDOMに置き換わっただけです。

ほかのフロントエンドフレームワークでも同様に、ShadowDOMにマウントさせればよいだけです。Vue.jsの例はこちらです。

Reactでカスタムエレメントを使う

基本的には、 divspan と同様に、エレメントを書くだけで十分に動作します。以下は、タグ入力ができるカスタムエレメントをReactアプリケーションで表示してみています。入力したものをReactアプリケーションで受け取れるようにする方法は次の項目で説明します。

カスタムエレメントのイベントを受け取る

カスタムエレメントから何らかのイベントを受け取りたいと思うこともあるでしょう。例えば、上のサンプルのカスタムエレメントは、複数のタグを入力できるようにする入力用のエレメントでした。このようなエレメントからは、エンターキーを入力される度に入力されたタグの配列を受け取れたりすると嬉しいですね。

また、どのようなフロントエンドフレームワークでも利用できることを目指すため、Webの標準的な機能「カスタムイベント」を使うのがよいでしょう(と思ったのですが、IE11は微妙に対応していないようです。今回は無視します。)。

以下のように tag-input のイベントを受け取って、画面に描画することができます。実際にイベントを送出しているコードはこちらです。

一方で、このようなイベント送出方法にはReactなどは対応していません。理由などはこちらが参考になりました。Reactからカスタムエレメントを描画して、イベントを受け取りたい!というような場合には、refsなどを使って実際のDOMに対してaddEventListenerするようなコードを書く必要がありそうです。

まとめ

フロントエンドフレームワークでカスタムエレメントを使う方法、定義する方法とその応用について書きました。

小さなコンポーネントをカスタムエレメントとして使うのは煩雑なコードが増えそうなので、ちょっと大変だなと感じました。

以上です。よろしくお願いします。

最後に

ユーザベースではエンジニアを募集中です。ご興味がございましたら、UzabaseのCareerページをぜひご覧ください。「エンジニア」で検索してもらえればと思います。

apply.workable.com

© Uzabase, Inc. All rights reserved.