Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Using React inside Elm

Register Element

First you will need document-register-element

yarn add document-register-element

Add script to register elements

Create a JS function to register React Components as Custom elements. See registerCustomElement.js below

Register the elements

e.g. HelloComponentCustomElement.jsx

import registerCustomElement from "registerCustomElement"

function HelloComponent(props) {
  return (
    <div>Hello</div>
  )
}

registerCustomElement(CustomComponent, "hello-component")

Import this script in your app

e.g. in App.js

// Custom Elements
import "app/widgets/HelloComponentCustomElement.jsx"

Use the custom element in Elm

e.g. in View.Elm

node "hello-component" [ attribute "some-prop" encodedJsonValue ] []
// @flow
// Adapted from https://github.com/bspaulding/react-custom-element
import "document-register-element"
import bows from "bows"
import React from "react"
import ReactDOM from "react-dom"
import rollbar from "shared/services/rollbar"
const log = bows("registerCustomElement")
function render(ComponentClass: React$ComponentType<any>) {
return function() {
const attributesCopy = [].slice.call(this.attributes)
const props = attributesCopy.reduce((attrs, attr) => {
attrs[attr.nodeName] = attr.nodeValue
return attrs
}, {})
ReactDOM.render(
<ComponentClass {...props} />, this
)
}
}
function detach() {
ReactDOM.unmountComponentAtNode(this)
}
function created() {
// Flow requires createdCallback
}
// TODO: Type ComponentClass properly
function registerCustomElement(ComponentClass: any, tagName: string) {
const elementPrototype = Object.create(HTMLElement.prototype)
elementPrototype.attachedCallback = render(ComponentClass)
elementPrototype.attributeChangedCallback = render(ComponentClass)
elementPrototype.detachedCallback = detach
elementPrototype.createdCallback = created
try {
return document.registerElement(tagName || ComponentClass.displayName, {
prototype: elementPrototype,
})
} catch(e) {
rollbar.error(e)
}
}
export default registerCustomElement
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.