As pointed out, this doesn't work as-is because of onload
, but may help someone else looking for something similar
You can always render a React component--'til you get around to rewriting it ;)--inside an Elm node. The trick is going to be mounting it. Shooting from the hip: it'd be a little hacky (and a bit expensive with a Json.Encode.encode
and JSON.parse
since you have to get the data out of Elm and into a consumable JS format for the component), but assuming you have ThatComponent
, React
, and ReactDOM
on the window
object you could try something along the lines of
import Html exposing (Html, div)
import Html.Attributes as Attr exposing (attribute)
import Json.Encode as Encode exposing (Value)
reactComponent : String -> (a -> Value) -> a -> Html msg
reactComponent componentName encoder data =
let
jsonProps : String
jsonProps =
Encode.encode 0 <| encoder data
-- a script to load the React component on `this` which is
-- the `div` element in this case.
onLoad : String
onLoad =
String.join ""
[ "javascript:"
, "window.ReactDOM.render("
, "window.React.createElement(window[\""
, componentName
, "\"], JSON.parse("
, jsonProps
, ")), this)"
]
in
div [ attribute "onload" onLoad ] []
What you will have though is a problem with it maintaining its own state--which is obviously bad and runs against the Elm architecture (but you probably know that and want to reuse something pre-built). You can use ports to send in data back in, but you'd want to wrap that reactComponent
in Html.Lazy.lazy3
so it doesn't rerender itself (which is why you'd send in both the encoder and data separately).