Introduction to React

A Javascript Library For Building User Interfaces

Oliver Zeigermann / @DJCordhose

Online version at: http://djcordhose.github.io/serious-javascript/slides/react-intro.html

Oliver Zeigermann

Who uses React?

http://facebook.github.io/react/blog/2014/09/12/community-round-up-22.html

React

http://facebook.github.io/react/

https://github.com/facebook/react

Concepts

  • Just the V in MVC
  • Based on components
  • Templates can be written in pure JavaScript or using the JSX template language
    • JSX can be rendered on the fly or
    • precompiled into JS for production
  • Uses a virtual DOM (tree structure) as view representation
  • Reactive one-way data-binding: Changes to state will be rendered automatically
  • Smart diffing algorithm computes the changes between old and new virtual DOM
  • Browser DOM experiences minimal amount of updates
  • Runs both on server and on client side

Hello World

<!DOCTYPE html>
<html>
<head>
    <script src="http://fb.me/react-0.10.0.js"></script>
    <script src="http://fb.me/JSXTransformer-0.10.0.js"></script>
</head>
<body>
<div id="example"></div>
<script type="text/jsx">
      /** @jsx React.DOM */
      React.renderComponent(
        <h1>Hello, world!</h1>,
        document.getElementById('example')
      );
    </script>
</body>
</html>
Run

A Simple Component

/** @jsx React.DOM */
var mountNode = document.getElementById('example');
var HelloMessage = React.createClass({
  render: function() {
    return <div>Hello {this.props.name}</div>;
  }
});

React.renderComponent(<HelloMessage name="Olli" />, mountNode);

Run

  • React.createClass: creates a component class
  • render: creates a virtual DOM tree (maybe using JSX)
  • this.props / input: something passed into component instance as input

A Simple Component - Compiled

var mountNode = document.getElementById('example');

var HelloMessage = React.createClass({displayName: 'HelloMessage',
    render: function() {
        return React.DOM.div(null, "Hello ", this.props.name);
    }
});

React.renderComponent(HelloMessage( {name:"Olli"} ), mountNode);

Run

  • React.renderComponent(ReactComponent component, DOMElement container): renders a component into a DOM element
  • React.renderComponentToString: for server side rendering
  • React: Top-Level API

Rendering a list

var TodoList = React.createClass({
  render: function() {
    var createItem = function(itemText) {
      return <li>{itemText}</li>;
    };
    return <ul>{this.props.items.map(createItem)}</ul>;
  }
});
<TodoList items={['Stuff', 'More Stuff']} />

State and passing it

var TodoApp = React.createClass({
  getInitialState: function() {
    return {items: ['Do stuff', 'Do more stuff']};
    },
  render: function() {
    return (
      <div>
        <h3>TODO</h3>
        <TodoList items={this.state.items} />
      </div>
    );
  }
});
React.renderComponent(<TodoApp />, mountNode);

Run

Update to state

var TodoApp = React.createClass({
  render: function() {
    return (
      <div>
        <h3>TODO</h3>
        <TodoList items={this.state.items} />
        <form onSubmit={this.handleSubmit}>
          <input onChange={this.onChange} value={this.state.text} />
          <button>{'Add #' + (this.state.items.length + 1)}</button>
        </form>
      </div>
    );
  }
  onChange: function(e) {
    this.setState({text: e.target.value});
  },
  handleSubmit: function(e) {
    e.preventDefault();
    this.state.items.push(this.state.text);
    this.setState({items: this.state.items, text: ''});
  }
});

Run

Comparing to other SPA Frameworks

  • No framework (vanilla.js)
  • jQuery
  • AngularJS

The App: Hello World React

var HelloMessage = React.createClass({
  getInitialState: function() {
    return { model: this.props.greeting};
  },
  updateModel: function(event) {
    this.setState({model: event.target.value});
  },
  reset: function() {
    this.setState({model: ""});
  },
  render: function() {
    return (<div>
        <input onChange={this.updateModel} value={this.state.model} />
        <p>{this.state.model}, World</p>
        <input type="button" value="Clear" onClick={this.reset} />
     </div>);
  }
});
var mountNode = document.getElementById('example');
React.renderComponent(<HelloMessage greeting="Hello" />, mountNode);
Run

Hello World vanilla.js

<input id="in" onkeyup="setModel(this.value)">
<p><span id="log"></span>, World</p>
<input type="button" value="Clear" onclick="reset()">
<script>
    var model;
    function setModel(value) {
        model = value;
        document.getElementById("log").innerHTML = model;
        document.getElementById("in").value = model;
    }
    function reset() {
        setModel("");
    }
    window.onload = function() {
        setModel("Hello");
    };
</script>
Run

Hello World jQuery

<input id="in">
<p><span id="log"></span>, World</p>
<input id="btn" type="button" value="Clear">
<script>
    var model;
    function setModel(value) {
        model = value;
        $("#log").html(model);
        $("#in").val(model);
    }
    $(document).ready(function () {
        $("#in").on("keyup", function (event) {
            setModel($("#in").val());
        });
        $("#btn").on("click", function () {
            setModel("");
        });
        setModel("Hello");
    });
</script>
Run

Option: AngularJS

  • HTML enhanced for web apps!
  • HTML extended by directives (=== components)
  • You can write your directives
  • 2-way data binding

Hello World AngularJS

<body np-app ng-controller="HelloController as helloController">
<input ng-model="helloController.greeting.text">
<p>{{helloController.greeting.text}}, World!</p>
<input type="button" value="Clear" ng-click="helloController.clear()">
</body>
function HelloController() {
    this.greeting = {
        text: 'Hello'
    };
}
HelloController.prototype.clear = function() {
    this.greeting.text = '';
};
Run

Wrap-Up

  • Just the V in MVC
  • One-Way-Binding
  • Minimal API for simplicity
  • Explicit code to avoid magic
  • React is heavily used in Facebook and Instagram
  • Changes to model will be rendered automatically
  • Browser DOM experiences minimal amount of updates
  • Can render both on server and on client side
  • Server side rendering also for SEO or quick first page impression

Links

Thank you!

Questions / Discussion

Oliver Zeigermann / @DJCordhose