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 を受け取る場合には、グローバルスコープに関数を登録する必要がある
childrenProps を受け取る場合には、string型として受け取るか、<slot>要素を使用する
