Upgrade to Pro — share decks privately, control downloads, hide ads and more …

React.js and Rails

React.js and Rails

Korstiaan de Ridder from Hoppinger talks about the successful integration of React.js and Rails for the holiday home rental platform Gites.nl. He explains the libraries we used, chosen approach, the challenges we met along the way, and the several possible further optimizations.

Korstiaan de Ridder

January 19, 2015
Tweet

Transcript

  1. R e a c t . j s a n

    d R a i l s w h a t e n a b l e d u s t o s t o p w o r r y i n g a n d l o v e J a v a S c r i p t DOOR: Korstiaan de Ridder DATUM: 19 Januari 2015 LOCATIE: Hoppinger, Rotterdam
  2. Who am I ? § Korstiaan de Ridder § Professional developer since

    2005 § Rails developer since 2013 § Using React.js since 3 months github.com/korstiaan twitter.com/korstiaan korstiaan.com
  3. #1 Brief history of JavaScript § Developed by Netscape in 1995

    in 10 days § Standardized in 1997 as ECMAScript § AJAX paper introduced in 2005 § jQuery initiated in 2006 § Backbone introduced in 2010
  4. #2 What is React.js? § Developed by Facebook in 2013 § Used

    by Airbnb, Netflix, Khan Academy, Gites.nl, Sony, Yahoo, Atlassian, Instagram § Strongly opinionated § Few new concepts to learn
  5. #2 React.js What does it do? § The V in MVC

    § A clever way to prevent unnecessary re-renders (Virtual-DOM) § A solution to “callback hell” (Single-way binding) § Server-side prerendering (Isomorphic)
  6. #2 React.js Components § Control a branch of the DOM § May

    have child-components § Responsible for converting data to HTML Data may consist of § Properties (“configuration’, immutable) § State (mutable)
  7. #2 React.js window.Reactions = React.createClass getInitialState: -> reactions: @props.reactions getInitialProps:

    -> max_items: 10 render: -> reactions = @state.reactions.slice(0, @props.max_items).map (reaction) -> `<li><Reaction reaction={reaction} /></li>` `<div><ul>{reactions}</ul></div>` window.Reaction = React.createClass render: -> `<div>{this.props.reaction}</div>` $ -> React.render( React.createElement Reactions, reactions: ['foo', 'bar', 'crux', 'baz'], max_items: 2 document.getElementById('reactions') )
  8. #2 React.js Virtual DOM § Virtual-DOM is modified: extremely fast § Actual-DOM

    updates only sparingly § Only updates what needs to be updated: prevents needless re- renders
  9. #2 React.js Single way binding § A component binds data (“properties’)

    to its childs § Easy way to track data flow § Avoids common issues with events (loops, filling up stacks)
  10. #2 React.js – single way binding window.Reactions = React.createClass getInitialState:

    -> reactions: @props.reactions getInitialProps: -> max_items: 10 onRemoveReaction: (reaction) -> @setState reactions: _.without(@state.reactions, reaction) render: -> self = this reactions = @state.reactions.slice(0, @props.max_items).map (reaction) -> `<li> <Reaction onRemoveReaction={self.onRemoveReaction} reaction={reaction} /> </li>` `<div><ul>{reactions}</ul></div>` window.Reaction = React.createClass onReactionClick: -> @props.onRemoveReaction this.props.reaction render: -> `<a onClick={this.onReactionClick}>{this.props.reaction}</a>`
  11. #3 React.js Isomorphic § Components render both client- & server side

    Server side prerending § … makes our SEO friends happy § … avoids use of PhantomJS or the likes § … avoids writing templates twice § … avoids seeing the page being build up § … allows for caching
  12. #2 React.js JSX § Syntactic sugar for defining tree structure (React.js

    components/ elements) § Looks like mixing XML-tags with JS § Not required
  13. #2 React.js - JSX window.Reactions = React.createClass # ... render:

    -> self = this reactions = @state.reactions.slice(0, @props.max_items).map(reaction) -> React.createElement "li", null, React.createElement Reaction, onRemoveReaction: self.onRemoveReaction reaction: reaction React.createElement "div", null, React.createElement("ul", null, reactions) window.Reactions = React.createClass # ... render: -> self = this reactions = @state.reactions.slice(0, @props.max_items).map (reaction) -> `<li> <Reaction onRemoveReaction={self.onRemoveReaction}vreaction={reaction} /> </li>` `<div><ul>{reactions}</ul></div>` equals
  14. § https://github.com/reactjs/react-rails § Integration with the asset pipeline § JSX support § Components generators

    § View helpers to render unobtrusively § Prerending support in beta (we run it in production) § CoffeeScript support § Supports different JS VM's for prerending via ExecJS Node.js, Therubyracer, Therubyrhino (JRuby) #3 React.js and Rails
  15. #3 React.js and Rails # foo.html.haml = react_component('Reactions', { reactions:

    ['foo', 'bar', 'crux', 'baz'], max_items: 2 }, {prerender: true} )
  16. § Refactoring of a single page with lots of JS § No

    need for complex routing, controllers, etc. (the M and C in MVC) Requirements: § Maintainable § Fast § SEO and user friendly #4 Case: Gites.nl