log-house19113-768x670

react-to-web-component を使って React コンポーネントを Web Components に変換する

@r2wc/react-to-web-component は React コンポーネントを Web Components に変換するためのライブラリです。このライブラリを使用することで、React コンポーネントを任意の HTML 要素として使用することが可能になります。

@r2wc/react-to-web-component は React コンポーネントを カスタム要素 に変換するためのライブラリです。このライブラリを使用することで、React コンポーネントを任意の HTML 要素として使用することが可能になります。

使い方

例として、以下のような React コンポーネントがあるとします。

import React from "react";
 
export const HelloWorld = () => {
  return <p>Hello, World!</p>;
};

@r2wc/react-to-web-component を使用して、この React コンポーネントを Web Components に変換するには、以下のように記述します。

import r2wc from "@r2wc/react-to-web-component";
import { HelloWorld } from "./HelloWorld";
 
const HelloWorldComponent = r2wc(HelloWorld);
 
customElements.define("hello-world", HelloWorldComponent);

このコードを実行することで、<hello-world> というカスタム要素が作成され、React コンポーネントが Web Components として使用できるようになります。

<hello-world></hello-world>

カスタム要素の属性を受け取る

React コンポーネントが受け取る Props をカスタム要素の属性として受け取ることができます。例として以下の React コンポーネントは、name という Props を受け取ります。

import React from "react";
 
export const HelloName = ({ name }) => {
  return <p>Hello, {name}!</p>;
};

この React コンポーネントを Web Components に変換するには、Props オプションにオブジェクトを渡します。属性名をキー、Props の型を値として指定します。属性の値には以下の型を指定できます。

  • "string"
  • "number"
  • "boolean"
  • "array"
  • "json"
  • "function"

また、キャメルケース(CamelCase)の Props は自動でケバブケース(kebab-case)に変換されます。

import r2wc from "@r2wc/react-to-web-component";
import { HelloName } from "./HelloName";
 
const HelloNameComponent = r2wc(HelloName, {
  name: "string",
});
 
customElements.define("hello-name", HelloNameComponent);

以下のように <hello-name> 要素に name 属性を渡すことができます。

<hello-name name="Alice"></hello-name>

関数型 Props の受け取り

Props の型として "function" を指定する場合には、window オブジェクト(つまりグローバルスコープ)に関数を登録する必要があります。以下の例では、onClick という関数型 Props を受け取る React コンポーネントを Web Components に変換しています。

import r2wc from "@r2wc/react-to-web-component";
import { Button } from "./Button";
 
const ButtonComponent = r2wc(Button, {
  onClick: "function",
});
 
customElements.define("my-button", ButtonComponent);

onclick 属性に関数を登録するには、グローバルスコープで関数を定義し、属性の値として関数名を指定します。

<script>
  function handleClick() {
    alert("Hello, World!");
  }
</script>
 
<my-button on-click="handleClick"></my-button>

children の受け取り

React コンポーネントではよく children という Props を使用します。この children はコンポーネントの開始タグと終了タグの間に記述された要素を指しており、型としては React.ReactNode として扱われます。しかし Web Components に変換した場合には以下のように渡すことはできません。

<!-- bad -->
<my-component>
  <p>Hello, World!</p>
</my-component>

代替策の 1 つとして、children Props を string 型として受け取ることが挙げられます。

import r2wc from "@r2wc/react-to-web-component";
import { MyComponent } from "./MyComponent";
 
const MyComponentComponent = r2wc(MyComponent, {
  children: "string",
});
customElements.define("my-component", MyComponentComponent);

この場合は children 属性として文字列を渡すことができます。

<my-component children="Hello, World!"></my-component>

ただし、この方法では HTML 要素を渡すことができません。もう 1 つの方法として、React コンポーネントをラップして <slot> 要素を使用する方法があります。

import React from "react";
 
export const MyComponent = ({ children }) => {
  return (
    <p>
      {children}
      <slot />
    </p>
  );
};

<slot> 要素を有効にするために、shadow オプションを設定して Shadow DOM としてレンダリングされる必要があります。

import r2wc from "@r2wc/react-to-web-component";
import { MyComponent } from "./MyComponent";
 
const MyComponentComponent = r2wc(MyComponent, {
  shadow: "open",
});
 
customElements.define("my-component", MyComponentComponent);

以下のように <slot> 要素を使用して、HTML 要素を渡すことができます。

<my-component>
  <p>Hello, World!</p>
</my-component>

まとめ

  • @r2wc/react-to-web-component を使用することで、React コンポーネントを Web Components に変換することができる
  • できる Props をカスタム要素の属性として受け取るためには、Props オプションにオブジェクトを渡す
  • 関数型 Props を受け取る場合には、グローバルスコープに関数を登録する必要がある
  • children Props を受け取る場合には、string 型として受け取るか、<slot> 要素を使用する

参考


Contributors

> GitHub で修正を提案する
この記事をシェアする
はてなブックマークに追加

関連記事