Skip to content

Instantly share code, notes, and snippets.

@goldhand
Created October 19, 2018 00:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save goldhand/7a63d74a8fd828242c1475eb7f8ba61e to your computer and use it in GitHub Desktop.
Save goldhand/7a63d74a8fd828242c1475eb7f8ba61e to your computer and use it in GitHub Desktop.
React App into Web Component (proof of concept)
import * as React from 'react';
import toWebComponent from './WebComponent';
const styles = {
greeting: {
color: 'green',
},
user: {
color: 'blue',
}
};
const Greet = ({
user,
greeting,
attrs,
}) => (
<div>
<h1 style={styles.greeting}>{greeting}</h1>
<h3 style={styles.user}>{user}</h3>
<ul>
{attrs
? attrs.map(attr => <li key={attr.name}>{attr.name + ': ' + attr.value}</li>)
: null
}
</ul>
</div>
);
export default toWebComponent(Greet, 'greet-react');
import * as React from 'react';
import ReactDOM from 'react-dom';
const toWebComponent = (Component, name) => {
class WebComponent extends HTMLElement {
constructor(...args) {
super(...args);
this.mountPoint = document.createElement('span');
}
get props() {
return this._props;
}
set props(props) {
if (this._isRendered) {
this._props = props;
this.update();
} else {
this._props = props;
}
}
connectedCallback() {
this.attachShadow({mode: 'open'}).appendChild(this.mountPoint);
ReactDOM.render(
<Component {...this.props} />,
this.mountPoint,
);
this._isRendered = 1;
}
update() {
ReactDOM.unmountComponentAtNode(this.mountPoint);
ReactDOM.render(<Component {...this.props} />, this.mountPoint);
}
}
customElements.define(name, WebComponent);
return (props, mountPoint) => {
const component = document.createElement(name);
if (props) component.props = props;
if (mountPoint) mountPoint.appendChild(component);
return component;
}
};
export default toWebComponent;
import Greet from './Greet';
const mountPoint = document.getElementById("greet-user");
const greetProps = {
user: 'Will', greeting: 'Hello Good Sir!', attrs: [
{name: 'height', value: '6 feet'},
{name: 'hair', value: 'blond'},
{name: 'weight', value: 'HEY EASY BUDDY!'},
],
};
// const greetUser = Greet();
// greetUser.props = greetProps;
// mountPoint.appendChild(greetUser);
// -- or --
Greet(greetProps, mountPoint);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment