ReactのJSXの代わりにJadeを使う


CoffeeScript+JadeでReactを使えるか試してみました。

CoffeeScriptでの記述方法は以下のリソースを参考にしました。

React v0.13.0 Beta 1

なかなか情報がありませんでしたが、本家以外では以下のリソースを参考にさせていただきました。

React.jsをCoffeeScriptとjadeで書く
react-jadeでjadeテンプレートから仮想DOMを出力する

react-jade-loader

バンドルはwebpackを利用し、Jadeはreact-jade-loader
で変換しています。

サンプル

サンプルはReact v0.13.0 Beta 1と同じ内容のものからJadeを使うによう変更したものをGitHubへ置いています。

https://github.com/notice/react-jade - GitHub

gulp+webpackでビルドできるところまで書いてあります。
Webサーバはお好きなもので。

自作Componentを含めたJadeの変換をどうすればいいのかよくわかりませんでしたが、react-jadeのドキュメントとトランスパイルされたソースコードを見ながらやってみました。

react-jade

Jadeソース

app.jadeからcounterコンポーネントを呼び出しています。プロパティが正しく反映されるかどうか調べます。

app.jade
div
  Counter(initialCount=1)
counter.jade
div
  span Count :
  button(onClick=tick)= count

CoffeeScriptソース

app.jadeをreact-jade-loaderでコンパイルしておいて、React.createFactoryで生成したファクトリを渡すことでレンダリングすることができました。

app.coffee
React = require 'react'
_ = require 'lodash'
Counter = require 'counter'
tmpl = require './app.jade'

class App extends React.Component
  constructor: (props) ->
    super props
  render: => tmpl(_.assign {Counter: React.createFactory Counter}, @, @props, @state)

module.exports = App
counter.coffee
React = require 'react'
_ = require 'lodash'
tmpl = require './counter.jade'

class Counter extends React.Component

  @propTypes = initialCount: React.PropTypes.number
  @defaultProps = initialCount: 0

  constructor: (props) ->
    super props
    @state = count: props.initialCount
  tick: =>
    @setState count: @state.count + 1
  render: => tmpl(_.assign {}, @, @props, @state)

module.exports = Counter

ReactにはマークアップとViewのロジックは密であるべきという思想があるようなんで、この方法だと、これに反してしまうのかもしれません。