何度か書いてきた。 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
。あとはその組み合わせ。
苦労が嘘みたいに簡単だった。まだ何か漏れていそうだけど。