2016-12-28 3 views
9

Я знаю, что с использованием Elm компонентов («модули»? Еще изучающий язык) в пределах React является установленным шаблоном с libraries like react-elm-components, но есть ли способ сделать обратный?Есть ли способ использовать React Components внутри Elm?

например, что-то, как это возможно:

Top-level React App 
-> React layout/component 
    -> Elm components 

Но что об этом:

Top-level Elm App 
    -> Elm layout/components 
    -> React components 

Если это возможно, является 'вяз в самой нижней' рисунком выше? Попытка выяснить, почему на нем нет литературы &, это возможное объяснение.

ответ

4

Как было отмечено, это не работает, как есть из-за onload, но может помочь кому-то еще ищет что-то подобное

Вы всегда можете вынести Реагировать компонент - пока вы получаете вокруг переписывать его;) - внутри узла Вязов. Трюк собирается его установить. Съемка с бедра: это было бы немного взломанным (и немного дорогим с Json.Encode.encode и JSON.parse, поскольку вам нужно получить данные из Вязов и в расходный JS-формат для компонента), но при условии, что у вас есть ThatComponent, React и ReactDOM на window объекта, который вы могли бы попробовать что-то вдоль линий

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 ] [] 

то, что вы будете иметь, хотя проблема с этим сохраняя свое состояние - которое, очевидно, плохо и работает против архитектуры Вязов (но вы, вероятно, знаете это и хотите повторно использовать что-то заранее построенное). Вы можете использовать порты для отправки данных обратно, но вы хотите обернуть это reactComponent в Html.Lazy.lazy3, чтобы он не перерегистрировал себя (поэтому вы отправляете как кодер, так и данные отдельно).

+1

спасибо @ toastal - между анализом и советами Другого ответа, это звучит, как это может быть донкихотскими в лучшем случае - хотя использование гигантской экосистемы React - довольно заманчивый выигрыш. Может быть, я заберу вас, как только закончу учебники для новичков в Elm;) Но, скорее всего, я просто встряхню и сделаю перекомпоновку компонентов - возможно, большой опыт изучения. – Brandon

+1

Я не считаю, что это работает, поскольку, по-видимому, div не поддерживает 'onload' https://stackoverflow.com/questions/22159476/simple-javascript-not-working-div-onload-alerthi –

9

Не делайте этого. Весь смысл Elm - шестиугольный дизайн. Elm должен функционировать как замкнутая система, в которой зло JS не может проникнуть. Вот почему вложение Elm в JS является первым классом, и у вас возникают проблемы с поиском обратного. Идея вложения React into Elm состоит в том, чтобы передать значение детерминизма и заверений Elm. Вы могли бы не использовать Elm вообще.

Если вы действительно хотите выполнять функциональное программирование в браузере и использовать компоненты React с архитектурой Elm, проверьте PureScript PUX. PUX предназначен для этого прецедента и даст вам лучшие результаты, чем взломать Elm, чтобы делать вещи. Elm был специально разработан для предотвращения.

Если мои комментарии не являются стартовыми для вас, я могу предложить следующий совет для того, чтобы быть злым таким образом, не зря.

Во-первых, вы можете выполнить это с помощью ports. Напишите приложение Elm для запуска событий в порту на JavaScript, когда вы хотите отобразить свой реагирующий компонент. Затем визуализируйте компонент реакции внутри пространства Elm Dom, стандартным способом с помощью JavaScript.

Второй (это самый близкий к тому, чтобы делать это правильно, что вы собираетесь получить), вы можете написать это, используя модули Elm Native. Это потребует от вас изучить недокументированную рабочую среду Элма и написать код, который будет взаимодействовать с ним. Что вы будете делать, так это написать пользовательский элемент HTML в системе низкого уровня Elm, который отобразит React внутри себя и управляет повторной рендерингом.

Удачи вам!

+0

Я не уверен, что это ответ по-прежнему остается верным, учитывая, что народ NoRedInk говорит о силе Вязов с веб-компонентами. Реагирование может не быть веб-стандартом, но идея небольших карманов компонентов состояния на странице Elm больше не является no-no –

+0

Это ответ на реакцию. Веб-компоненты - отдельная тема. – Fresheyeball

1

Я пытался сделать то же самое. Я взял популярный сборщик данных React и начал с взаимодействия через порты. Это все еще в стадии разработки, но работает

import React from 'react'; 
import ReactDOM from 'react-dom'; 

import * as Datetime from 'react-datetime' 

function datepicker(d, cb) { 
    return requestAnimationFrame(() => { 
     ReactDOM.render(Welcome(d, (res) => { 
      cb(res); 
     }), document.getElementById('reactDate'));    
    }); 
} 

function Welcome(initialdate, cb) { 
    return (
     <div> 
     <h1>{initialdate}</h1> 
     <Datetime onChange={cb} value={initialdate} /> 
    </div> 
); 
} 

export default datepicker; 

Тогда мой порты код выглядит

import datepicker from './reactDPPort.jsx'; 
elm.ports.trigger.subscribe((s) => { 
    datepicker(s, res => app.ports.toElm.send(res.toString())); 
}); 
Смежные вопросы