react-railsがとてもよさそうなのでjsx部をslimで書きたい

[追記]コメントで素直な対処法をいただきました。

素直な対処法

とてもうれしい。


最高になったらしいのですが、それはともかくrails者のわたしはslimで書きたいので(今後react-slimとか出てくることを期待して)とりあえず書けるみたいなレベルで乱暴な解決を試みた。

しあがり

<%
  def brutal_slim_jsx(src)
    clean_brutally(Slim::Template.new(pretty: false) { src }.render).tap{|r| p r}
  end

  def brutal_slim_jsx_file(file)
    clean_brutally(Slim::Template.new(file, {}).render).tap{|r| p r}
  end

  def clean_brutally(rendered)
    rendered.gsub("\"{{", '{').gsub("}}\"", '}')
  end
%>

@HelloMessage = React.createClass(
  render: ->
    `<%= brutal_slim_jsx <<-EOS
        div[className="message"]
            NamePlate[name="{{this.props.name}}"]
        EOS
      %>`
    )

@NamePlate = React.createClass(
  render: ->
    `<%= brutal_slim_jsx_file("#{Rails.root}/app/assets/jsx/name_plate.html.slim") %>`
    )
p[className="name-plate"]= "{this.props.name}"
<div data-react-class="HelloMessage" data-react-props="{&quot;name&quot;:&quot;John&quot;,&quot;gender&quot;:&quot;male&quot;}">
  <div class="message" data-reactid=".1fnjtypkz5s" data-react-checksum="294791015">
    <p class="name-plate" data-reactid=".1fnjtypkz5s.0">John</p>
  </div>
</div>

準備

https://github.com/reactjs/react-railsServer renderingまでやる。

しあげ

coffee側の拡張子は.jsx.coffee.erb、slimはjsxっぽくrenderされるようにする。

slim->htmlのrenderではattributesからダブルクオートをはがせないので置換でなんとかする。

tappしてるのは何度もrenderされてないか確認用。

便利記法は使えない

JSXの便利記法がいろいろあると思うんですが、そういうの使いたい場合は生展開で。

@HelloMessage = React.createClass(
  render: ->
    `<%= brutal_slim_jsx <<-EOS
        div[className="message"]
          | <NamePlate {...this.props} />
        EOS
      %>`
    )

まとめ

このやりかたでは労と安全性のなさに対して得るものが少なそう。