react-to-webcomponent converts React components to custom elements! It lets you share react components as native elements that don't require mounted being through React. The custom element acts as a wrapper for the underlying react component. Use these custom elements in any framework (vue, svelte, angular, ember, canjs) the same way you would use standard HTML elements.
react-to-webcomponent:
- Works in all modern browsers. (Edge needs a customElements polyfill).
- Is
1.11KBminified and gzipped.
Given a react component like:
class Greeting extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}Call reactToWebComponent and customElements.define as follows:
import reactToWebComponent from "react-to-webcomponent";
const WebGreeting = reactToWebComponent(Greeting, React, ReactDOM);
customElements.define("web-greeting", WebGreeting);Now you can use <web-greeting> like any other HTML element!
You can create it programatically:
const webGreeting = document.createElement("web-greeting");
webGreeting.name = "StandardsFan";
document.body.append(webGreeting);
webGreeting.innerHTML //-> "<h1>Hello, StandardsFan</h1>"Or you can use it declaratively:
document.body.innerHTML = "<web-greeting></web-greeting>";
document.body.firstChild.name = "CoolBeans";
document.body.firstChild.innerHTML //-> "<h1>Hello, CoolBeans</h1>"By default, custom elements created by reactToWebComponent only
pass properties to the underlying React component. To make attributes
work, you must specify your component's properties with
PropTypes as follows:
class Greeting extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
Greeting.propTypes = {
name: PropTypes.string.isRequired
};Now reactToWebComponent will know to look for name attributes
as follows:
document.body.innerHTML = "<web-greeting name='Amazed'></web-greeting>";
document.body.firstChild.innerHTML //-> "<h1>Hello, Amazed</h1>"To install from npm:
npm i react-to-webcomponent
reactToWebComponent(ReactComponent, React, ReactDOM, options) takes the following:
ReactComponent- A react component that you want to convert to a Web Component.React- A version of React (or preact-compat) the component works with.ReactDOM- A version of ReactDOM (or preact-compat) that the component works with.options- An optional set of parameters.options.shadow- Use shadow DOM rather than light DOM.
A new class inheriting from HTMLElement is
returned. This class can be directly passed to customElements.define as follows:
customElements.define("web-greeting",
reactToWebComponent(Greeting, React, ReactDOM) );Or the class can be defined and used later:
const WebGreeting = reactToWebComponent(Greeting, React, ReactDOM);
customElements.define("web-greeting", WebGreeting);
var myGreeting = new WebGreeting();
document.body.appendChild(myGreeting);Or the class can be extended:
class WebGreeting extends reactToWebComponent(Greeting, React, ReactDOM)
{
disconnectedCallback(){
super.disconnectedCallback();
// special stuff
}
}
customElements.define("web-greeting", WebGreeting);Components can also be implemented using shadow DOM.
const WebGreeting = reactToWebComponent(Greeting, React, ReactDOM, { shadow: true });
customElements.define("web-greeting", WebGreeting);
var myGreeting = new WebGreeting();
document.body.appendChild(myGreeting);
var shadowContent = myGreeting.shadowRoot.children[0];reactToWebComponent creates a constructor function whose prototype is a Proxy. This acts as a trap for any property set on instances of the custom element. When a property is set, the proxy:
- re-renders the React component inside the custom element.
- creates an enumerable getter / setter on the instance to save the set value and avoid hitting the proxy in the future.
Also:
- Enumerable properties and values on the custom element are used as the
propspassed to the React component. - The React component is not rendered until the custom element is inserted into the page.