Edited Jan 13, 2014 with minor changes which allow for testing timeouts in Ember.
We engineers at Instructure love Ember. We also love to learn about other frameworks and know which tools are the best for the job at hand. One of the newer frameworks to come out is React.
React is Facebook’s new JavaScript library for building user interfaces. I’m excited to see another player in the game of front-end JS frameworks. When we have so much mind share going to a similar problem, we all win.
On the home page (screenshot), there are a few examples of how React can be used. I thought it might be fun to show how each of these can be done using Ember.
A Simple Component
React components take data and return content which is to be displayed. Here’s their example code:
Since we are maintaining state within the component itself, let’s build it using an Ember Component.
Ember
1234567891011121314151617181920212223
App.TimeOnPageComponent=Em.Component.extend({secondsViewed:0,// Increment the secondsViewed attributetick:function(){this.incrementProperty('secondsViewed');},onInterval:function(){Ember.run(this,this.tick);},// Initiates timer when element is renderedstartTimer:function(){this._interval=setInterval(this.onInterval.bind(this),1000);}.on('didInsertElement'),// Ensure that the timer stops when closedclearInterval:function(){clearInterval(this._interval);this._interval=null;}.on('willDestroyElement')});
The application example is a simple todo list which has a TodoList class (for rendering content) and a TodoApp class (maintains the state and renders the layout). Here’s the code:
When writing this in Ember, we would use both a controller and a handlebars template. The controller will maintain the state and respond to user interaction and the template will display the form and list.
/** @jsx React.DOM */varconverter=newShowdown.converter();varMarkdownEditor=React.createClass({getInitialState:function(){return{value:'Type some *markdown* here!'};},handleChange:function(){this.setState({value:this.refs.textarea.getDOMNode().value});},render:function(){return(<divclassName="MarkdownEditor"><h3>Input</h3><textareaonChange={this.handleChange}ref="textarea"defaultValue={this.state.value}/><h3>Output</h3><divclassName="content"dangerouslySetInnerHTML={{__html:converter.makeHtml(this.state.value)}}/></div>);}});React.renderComponent(<MarkdownEditor/>,mountNode);
The caveat to this example is that it assumes that the showdown library is already loaded. In our Ember example, note that the library is loaded in the head.
Ember (controller)
1234567891011
App.ApplicationRoute=Em.Route.extend({model:function(){return{value:'Type some *markdown* here!'};}});Em.Handlebars.registerBoundHelper('markdown',function(str){varconverter=newShowdown.converter();varhtml=converter.makeHtml(str||'');returnnewHandlebars.SafeString(html);});
I haven’t spent enough time with React to be able to convert the Ember examples to it, but I would love to see someone do that for a better comparison.
Eric Berry is a software engineer at Instructure and loves giving back to the community via blog posts and meetups. He was a co-founder of ShareAPhoto, Ltd, a European online photo sharing company which was acquired by Hewlett-Packard in 2006. He was the author of Rails Pocket Reference (published 2008 – O’Reilly). He spear-headed TeachMeToCode.com, a popular on-demand screencasting website dedicated to helping others learn how to program.