有没有办法在Elm中使用React组件?

Bra*_*don 10 elm reactjs

我知道使用Elm组件("模块"?仍在学习用语)React是一个已建立的模式react-elm-components,但有没有办法做反向?

例如,这样的事情是可能的:

Top-level React App
 -> React layout/component
    -> Elm components
Run Code Online (Sandbox Code Playgroud)

但是这个怎么样:

Top-level Elm App
  -> Elm layout/components
     -> React components
Run Code Online (Sandbox Code Playgroud)

如果可能的话,'榆树底部'模式是否优越?试图解释为什么似乎没有关于它的文献,这是一个可能的解释.

Fre*_*all 9

不要那样做.榆树的重点是六边形设计.榆树的目的是作为一个封闭的系统,JS的邪恶无法渗透.这就是为什么在JS中嵌入Elm是一流的,并且你在查找反向时遇到了这样的麻烦.将React嵌入Elm的想法是交出Elm的决定论和保证的价值.你可能根本不使用榆树.

如果您真的只想在浏览器中进行函数式编程并使用带有Elm架构的React组件,请查看PureScript PUX.PUX专为该用例而设计,并且可以为您提供比黑客榆树更好的结果来做Elm专门设计用来防止的事情.

如果我的评论对你来说不起作用,我可以通过这种方式为邪恶提供以下建议,而不是太邪恶.

首先,您可以完成此任务ports.当您想要渲染您的反应组件时,将您的Elm应用程序编写为将端口上的事件激活到JavaScript.然后使用JavaScript以标准方式渲染Elm Dom空间内的react组件.

第二个(这是你最接近正确的做法),你可以使用Elm Native模块来编写它.这将要求您学习Elm的未记录的运行时,并编写与之交互的代码.你要做的是在Elm的低级系统中编写一个自定义的Html元素,它将React内部渲染并管理重新渲染.

祝好运!


toa*_*tal 4

正如所指出的,这不能按原样工作,因为onload,但可能会帮助其他人寻找类似的东西

您始终可以在 Elm 节点内渲染 React 组件——直到您有时间重写它;)。诀窍是安装它。从臀部开始:这有点老套(而且使用Json.Encode.encodeand有点昂贵JSON.parse,因为你必须从 Elm 中获取数据并转换为组件的可用 JS 格式),但假设你有、ThatComponentReact和反对你可以尝试一些类似的事情ReactDOMwindow

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 ] []
Run Code Online (Sandbox Code Playgroud)

但你会遇到一个问题,那就是它维护自己的状态——这显然很糟糕,并且违背了 Elm 架构(但你可能知道这一点,并且想要重用预先构建的东西)。您可以使用端口将数据发送回,但您希望将其包装reactComponent起来Html.Lazy.lazy3,这样它就不会重新渲染自身(这就是为什么您要分别发送编码器和数据)。