Intro to React

Chicago ReactJS Meetup #1!!!!!

My one big statement.

The ideas behind
REACT
have changed
web development.

Hey guy, what are these ideas?

Meet Pete Hunt of the Core React Team.

Pete says amazing things like:

"Reduce coupling, increase cohesion"
"Mutable state is the root of all evil."
"React components are just idempotent functions"

..and he can back up those statements.

Watch his talks about React, srsly.

@JoeMaddalone

Technical Architect at Universal Mind

Instructor at egghead.io

youtube.com/joemaddalone

JavascriptOO.com

Filltext.com

NOT AS COOL AS PETE HUNT

"Reduce coupling, increase cohesion"

Use JavaScript, not templates


"Mutable state is the root of all evil."

State is hard. Just Re-render everything.


"React components are just idempotent functions"

React components are just functions

Use JavaScript, not templates?

Now you say, "but, what about separation of concerns?"

then I say, "We never had it.... muwahahahah"

In a not so bad world

JavaScript

return BaseView.extend( {
  initialize: function ( options ) {
    new Collection().fetch().then(function(data){
      this.collection = data;
    })
  },
  render: function () {
    var template = _.template( myViewTemplate, {collection: this.collection} );
    this.$el.html( template );
  }
} );

In a not so bad world

template

<ul>
  <% _.each( collection, function( item ){ %>
  <li><%= item.get("title") %></li>
  <% }); %>
</ul>

In the real world, concern #1...

return BaseView.extend( {
  events: {
    'click .filterModel': 'aHandler'
  },
  aHandler: function( e ){
    e.preventDefault();
    renderAgain( _.extend( this.collection, {
      model: $( e.currentTarget ).data( 'modelNumber' )
    } ) );
  },
  render: function () {...}
  renderAgain: function ( newState ) {...}
} );

... looks a lot like concern #2

<ul>
  <% _.each( collection, function( item ){ %>
  <li>
    <p><%= item.get("title") %></p>
    <button
      class="filterModel"
      data-modelNumber="<%= item.get( "modelNumber" ) %>">
      This Models
    </button>
  </li>
  <% }); %>
</ul>

this is coupling
not separation

and it requires reinventing concepts we already have in Javascript

{{#each item in collection}} <!-- loop -->
{{#if item.active}} <!-- conditional -->
  {{item.title}}
{{/if}}
{{/each}}
<div ng-repeat="item in collection"> <!-- loop -->
  <div ng-show="item.active"> <!-- conditional -->
    {{item.title}}
  </div>
</div>

The problem with coupling:

  • A change in one module usually forces a ripple effect of changes in other modules.
  • Assembly of modules might require more effort and/or time due to the increased inter-module dependency.
  • A particular module might be harder to reuse and/or test because dependent modules must be included.

-- http://en.wikipedia.org/wiki/Coupling_(computer_programming)

Okay, so no more templates, but what then?


I ain't doing this horsesh*t

var HelloWorld = document.createElement('h1');
HelloWorld.id = "Hello";
HelloWorld.innerHTML = "Hello World";
document.body.appendChild(HelloWorld);

Any guess what this does?

React.render(React.DOM.h1({id: 'Hello'}, 'Hello World'), document.body);
<body>
  <h1 id="Hello">Hello World</h1>
</body>

How about this?

var HelloWorld = React.createClass({
  render: function(){
    return React.DOM.h1({id: 'Hello'}, 'Hello World');
  }
})
React.render(HelloWorld(), document.body);
<body>
  <h1 id="Hello">Hello World</h1>
</body>

... and what the hell is this?

var HelloWorld = React.createClass({
  render: function(){
    return <h1 id="Hello">Hello World</h1>
  }
})
React.render(<HelloWorld />, document.body);
<body>
  <h1 id="Hello">Hello World</h1>
</body>

Demo

Component Basics
"Reduce coupling, increase cohesion"

Use JavaScript, not templates

State is hard. Just Re-render everything.

...not really, but it sounds cool.

The olden "server-side" days

we just refreshed the entire page

In modern frontend development

We can't just tear down the entire DOM for every update.

React offers a solution to this problem

This is not a DOM operation

render: function(){
  return <h1>Hello World!</h1>
}

It's a description of the DOM for...

THE
VIRTUAL
DOM

of awesomesauce

Our initial description of the DOM generates the initial virtual DOM

Then on every update React...

  • builds a JS representation of the DOM from the point of change
  • compares that subtree with the old one
  • pushes the minimal set of DOM updates into a queue
  • and batch executes all those updates

The Virtual DOM Goodness

  • Re-renders are FAST, dont sweat them
  • The state of your app is easy to identify
  • Optimizations are a shouldComponentUpdate away
  • Testing is easy, everything is a function

Thirsty?

Here's the kool-aid you need to drink.

No Data Binding

Just One-way reactive data flow

Data flows down, events flow up

Just like the DOM, but better

Also no...

controllers

directives

models

templates

view models

ProviderProviders

Demo

Data Flow

React components are just functions

So it's easy to...

Get started by updating small sections of your UI

$(document).on('click', '.show', function(){
  React.render(Component(), someElement);
});

$(document).on('click', '.remove', function(){
  React.unmountComponentAtNode(someElement);
})

Integrate third-party libraries

var App = React.createClass({
  render:function(){
    return (
      <select>
        <option value="AL">Alabama</option>
        ...
        <option value="WY">Wyoming</option>
      </select>
    )
  },
  componentDidMount:function(){
    $(this.getDOMNode()).selectPlugin();
  },
});

Test

var test = React.addons.TestUtils;
describe('Component', function() {
  it('should have a val of 1', function() {
    var c = test.renderIntoDocument(Component());
    test.Simulate.click(c.refs.buttonA.getDOMNode());
    c.state.val.should.equal(1);
  });
});

And since React isnt tied to the DOM, server side rendering

http.createServer(function(req, res) {
  var props = {items: [0, 1]}

  var myAppHtml = React.renderToString(MyApp(props))
  /* OR */
  var myAppHtml = React.renderToStaticMarkup(MyApp(props))

  res.setHeader('Content-Type', 'text/html')
  res.end(myAppHtml)
}).listen(3000)

A little shilling

egghead.io

React, Flux, Angular, D3, node, ES6, and more

Discount code

egghead.io/pricing?dc=maddalone

Questions?