2018-06-11 Halogen の Component を今度こそ String にする話
何度か書いてきた。 slamdata/purescript-halogen の Component を String にする話。過去の記事は↓あたり。
Halogen の Component を String にしたい。 server side rendering する際に Component をそのまま使えると (実行効率はともかく) 何度も書かなくて済む。こんなことくらい当然のように書いてあると思いきや、情報がなくていろいろ模索した。さんざん苦労したのに Component をバラす方法に変えたら、あっという間に動いてしまった。
細かい説明は面倒なので、ソースコードを示す。
module Bouzuya.Halogen.StringRenderer (render) where
import Halogen as H
import Halogen.HTML as HH
import Halogen.VDom.DOM.StringRenderer as VSR
import Prelude (Unit)
render
  :: forall f i o m
  . H.Component HH.HTML f i o m
  -> i
  -> String
render = componentToString
componentToString
  :: forall f i o m
  . H.Component HH.HTML f i o m
  -> i
  -> String
componentToString component input =
  H.unComponent
    (\{ initialState, render } ->
      let (HH.HTML vdom) = render (initialState input) in
      VSR.render componentSlotToString vdom
    )
    component
componentSlotToString
  :: forall f g m p
  . H.ComponentSlot HH.HTML g m p (f Unit)
  -> String
componentSlotToString slot =
  H.unComponentSlot
    (\_ component input _ _ _ -> componentToString component input)
    slot
雑に言うと unComponent と unComponentSlot を使って Component やその子である ComponentSlot をバラして、あとは Halogen.VDom.DOM.StringRenderer の render に食わせる。バラしたものは initialState と render そして input くらいしか使わない。 initialState は Input -> State 。 render は State -> HTML ... 。 input は Input 。あとはその組み合わせ。
苦労が嘘みたいに簡単だった。まだ何か漏れていそうだけど。