如上所述,由于
onload
的原因,这个方法本身是无法正常工作的,但可能会对寻找类似内容的其他人有所帮助。
你可以在 Elm 节点内部始终呈现 React 组件(在重写之前)。关键是如何挂载它。粗略地说:这可能会有点 hacky(并且使用
Json.Encode.encode
和
JSON.parse
会有点昂贵,因为你必须将数据从 Elm 中取出并转换成可消费的 JS 格式以供组件使用),但假设你已经在
window
对象上拥有
ThatComponent
、
React
和
ReactDOM
,你可以尝试以下操作:
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
onLoad : String
onLoad =
String.join ""
[ "javascript:"
, "window.ReactDOM.render("
, "window.React.createElement(window[\""
, componentName
, "\"], JSON.parse("
, jsonProps
, ")), this)"
]
in
div [ attribute "onload" onLoad ] []
你将会遇到一个问题,那就是它无法维护自身的状态——这显然不好,也违背了Elm架构(但你可能已经知道了并且想要重用一些预先构建好的东西)。你可以使用端口将数据发送回来,但你需要在
Html.Lazy.lazy3
中包裹
reactComponent
,这样它就不会重新渲染自己了(这也是为什么你需要分别发送编码器和数据)。