React & CoffeeScript

Multiple people asked what's the story about JSX and CoffeeScript. There is no JSX pre-processor for CoffeeScript and I'm not aware of anyone working on it. (If you are interested in writing one, you probably should look at CoffeeScriptRedux). Fortunately, CoffeeScript is pretty expressive and we can play around the syntax to come up with something that is usable.

Example

Let's see how JSX look like with an example:

<div className="MarkdownEditor">
  <h3>Input</h3>
  <textarea onKeyUp={this.handleKeyUp} ref="textarea">
    {this.state.value}
  </textarea>
</div>

which desugars to the following

React.DOM.div({className: 'MarkdownEditor'}, [
  React.DOM.h3({}, 'Input'),
  React.DOM.textarea({onKeyUp: this.handleKeyUp, ref: 'textarea'},
    this.state.value
  )
])

We can easily translate it to CoffeeScript:

{div, h3, textarea} = React.DOM
(div {className: 'MarkdownEditor'}, [
  (h3 {}, 'Input'),
  (textarea {onKeyUp: @handleKeyUp, ref: 'textarea'},
    @state.value
  )
])

Structure

The translations rules are really easy. The only gotcha is to write the tags wrapped in parenthesis lisp-style. This is the best way I found not to get caught with indentation issues.

# Empty element
# <div></div>
(div {})
 
# Text children: You use a string literal
# <div>foo</div>
(div {}, 'foo')
 
# Interpolation: You ignore the {} and write the expression as is
# <div>{this.state.text}</div>
(div {}, @state.text)
 
# Multiple children: You use the [] notation
# <div>
#  <br />
#  <br />
# </div>
(div {}, [
  (br {}),
  (br {})
])
 
# Attributes: You write them using {} notation
# <div onClick={this.onClick}></div>
(div {onClick: @onClick})

Demos

I've re-written all the React front-page examples using CoffeeScript. The translation was really easy.

Hello World

Timer

Todo

Markdown

If you liked this article, you might be interested in my Twitter feed as well.
 
  • Zack Gomez

    neat!

  • Myron

    Why not to use code like this:

    HelloMessage = React.createClass
    render: ->
    `{'Hello ' + this.props.name}`

    React.renderComponent ``, mountNode

    ?

  • Myron

    (sorry for corrupted formatting)

  • sankalp singha

    Thank you for this!! Really really informative!!

  • sankalp singha

    I have got this code :

    var Comment = React.createClass({
    render: function() {
    return (

    {this.props.author}

    {this.props.children}

    );
    }
    });

    How will this be converted into CS?
    I tried this, but I guess I am wrong somewhere?

    comment = React.createClass
    render : ->
    (div {className : "comment"},[ h2 {className : "commentAuthor"},[@props.author]])

 

Related Posts

  • August 27, 2011 -- Start a technical blog, it’s worth it! (3)
    Lately, I've been advocating to all my student friends to start a blog. Here's an article with the most common questions answered :) What are the benefits? Being known as an expert. The majority of my blog posts are about advanced Javascript topics. As a result, I'm being tagged as the "Jav...
  • September 17, 2011 -- WoW Interface Anchor Positioning (4)
    I've always found CSS positioning with both float and position: absolute/relative hard to work with. I want to introduce to you an alternative way borrowed from the World of Warcraft Interface: Anchors. Anchor The concept is extremely simple. You can tell where you want the element to be, rel...
  • November 5, 2011 -- Simulated Annealing Project (0)
    For a school project, I have to implement Simulated Annealing meta heuristic. Thanks to many open source web tools, I've been able to quickly do the project and have a pretty display. CoffeeScript, Raphael, Highcharts, Three.js, Twitter Bootstrap, jQuery and Web Workers. .hover-border img {...
  • December 7, 2011 -- Automatic Links with Trie (0)
    On MMO-Champion, we often paste World of Warcraft patch notes taken from Blizzard. The main problem is that it's plain text. We want to be able to add links to all the spells, quests, zones ... This way people can mouseover and see the description. It helps figuring out what changed. We create...
  • July 4, 2013 -- JSX for the real DOM (3)
    React is bundled with a Javascript transpiler called JSX. It gives the ability to write <html> tags within Javascript. The advertised way to use JSX is React.DOM to create React light DOM elements, but it is not the only way. We can create another JSX backend, called JSXDOM, to create real DOM...