DEV Community

e_ntyo
e_ntyo

Posted on

elm-tsでReactの代わりにPreactを使う

TL; DR

  • gcanti/elm-ts というライブラリがあり、fp-tsElm Architectureを実装している
  • elm-tsはvirtual-domの代わりにReactを使っているがPluggableである
    • > React instead of virtual-dom (pluggable)
    • しかし、具体的にどのように他のVirtual DOMの実装を使えばよいか具体的な記述はない
    • この記事ではPreactを使う場合の具体的なやり方を紹介する。おそらく同じやり方で他のVirtual DOMの実装(snabbdom-modulesなど)も使うことが出来るはず

やり方

一言で言えば、elm-ts/lib/ReactHtml インターフェースの代わりにPreact Compatibleな Html インターフェースを自前で定義して使えばok。

/** * `Dom` is a `ReactElement`. * @category model * @since 0.5.0 */ export interface Dom extends ReactElement<any> { } /** * `Html` has `Dom` type constrained to the specialized version for `React`. * @category model * @since 0.5.0 */ export interface Html<Msg> extends html.Html<Dom, Msg> { } 
Enter fullscreen mode Exit fullscreen mode

elm-ts/lib/ReactHtml インターフェースの定義はこんな感じなので、Dom(=ReactElement<any>)をPreact相当のものに差し替えればよさそう。

// Instead of Html, use PreactHtml export type PreactHtml<Msg> = Html<h.JSX.Element, Msg>; 
Enter fullscreen mode Exit fullscreen mode

よしなにview functionの定義で PreactHtml を使う。

export function view(model: Model): PreactHtml<Msg> { return <div>...</div> } 
Enter fullscreen mode Exit fullscreen mode

あとは programrun するだけだが、React.program を使うことはできないので elm-ts/lib/Htmlprogram を次のようにして使う。

import { programWithDebuggerWithFlags } from "elm-ts/lib/Debug/Html"; import { Flags, Model, Msg, flags, init, update, view } from "./App"; import { programWithFlags, run } from "elm-ts/lib/Html"; import { VNode, h, render } from "preact"; // React.programはもういないんだ const program = process.env.NODE_ENV === "production" ? programWithFlags : programWithDebuggerWithFlags; // もうあの時間は終わって、君も人生と向き合う時なんだ // programのGenericsの4つ目にpreactの VNode を使っているところに注意 const main = program<Flags, Model, Msg, VNode>(init, update, view); const app = document.getElementById("app"); if (app === null) { throw new Error("id=appな要素がない"); } run(main(flags), dom => render(dom, app)); 
Enter fullscreen mode Exit fullscreen mode

おわり。

おことわり

  • elm-tsはできて間もないライブラリなので仕様がすぐ変わり、このやり方では動かなくなるかも
    • 公式のREADMEにPRを出さずにBlog Postにした理由はこれ

Top comments (0)