Building UIs with React

Filip Petkovski

In the 90s it was easy

  • No RESTful APIs, no AJAX calls
  • Refresh the page whenever the data changes
  • JavaScript was simple

Fast forward to 2015

  • Building [good] web apps requires teams
  • Front end development is an engineering field
  • JavaScript has become fast enough for many tasks

Web apps are still slow

  • Native apps outperform web apps by a large margin
  • Frameworks like AngularJS 1.x make things worse
  • JavaScript execution is usually not the issue
  • The DOM is used for the wrong purpose

What impedes DOM speed

  • Frequent reflows and repaints
  • A repaint has to verify the visibility of all other nodes
  • A reflow affects the layout of the page

React overview

  • React is only a view library
  • Components and composition are central
  • One way binding
  • Virtual DOM

React component basics

  • Components are state machines
  • A component has internal state and external props
  • Components can be nested and reused
  • Written entirely in JavaScript or JSX
var Title = React.createClass({
    render: function() {
        return <h2>Form title</h2>
    }
});

var TextInput = React.createClass({
    render: function() {
        return (
            <div>
                <input type="text" />
            </div>
        );
    }
});

var Form = React.createClass({
    render: function() {
        return (
           <div className="form">
	       <Title />
	       <TextInput />
	   </div>
        );
    }
});
var Title = React.createClass({
    render: function() {
        return <h2>{this.props.title}</h2>
    }
});

var TextInput = React.createClass({
    render: function() {
        return (
            <div>
                <input type="text" />
            </div>
        );
    }
});

var Form = React.createClass({
    render: function() {
        var title = 'Custom title';
        return (
           <div className="form">
	       <Title title={title} />
	       <TextInput />
	   </div>
        );
    }
});
var TextInput = React.createClass({
    render: function() {
        return (
            <input type="text" 
                value={this.props.value} 
                onChange={this.props.changeHandler} />
        );
    }
});

var Form = React.createClass({
    getInitialState: function() {
        return { inputValue: 'Initial input value' };
    },

    changeInputValue: function(event) {
        this.setState( { inputValue: event.target.value } );
    },

    render: function() {
    	var title = 'Custom title';
        return (
            <div className="form">
	        <Title title={title} />
	        <TextInput 
                    value={this.state.inputValue} 
                    changeHandler={this.changeInputValue} />
	    </div>
        );
    }
});

Why one-way binding?

  • Achieving consistency is easy
  • No unexpected performance drops
  • Debugging is straightforward

What about performance?



var Form = React.createClass({
    // ...
    shouldComponentUpdate: function(nextProps, nextState) {

    },
    // ...
});

The case for immutability

  • Immutable.js for immutable collections
  • All modifications return a new collection
  • Testing for equality between collections is trivial

Immutable.js in action



var Form = React.createClass({
    // ...
    shouldComponentUpdate: function(nextProps, nextState) {
        return this.props.items !== nextProps.items;
    },
    // ...
});
  • A light implementation of the in-browser DOM

Virtual DOM

First level properties of <div />

align, onwaiting, onvolumechange, ontimeupdate, onsuspend, onsubmit, onstalled, onshow, onselect, onseeking, onseeked, onscroll, onresize, onreset, onratechange, onprogress, onplaying, onplay, onpause, onmousewheel, onmouseup, onmouseover, onmouseout, onmousemove, onmouseleave, onmouseenter, onmousedown, onloadstart, onloadedmetadata, onloadeddata, onload, onkeyup, onkeypress, onkeydown, oninvalid, oninput, onfocus, onerror, onended, onemptied, ondurationchange, ondrop, ondragstart, ondragover, ondragleave, ondragenter, ondragend, ondrag, ondblclick, oncuechange, oncontextmenu, onclose, onclick, onchange, oncanplaythrough, oncanplay, oncancel, onblur, onabort, spellcheck, isContentEditable, contentEditable, outerText, innerText, accessKey, hidden, webkitdropzone, draggable, tabIndex, dir, translate, lang, title, childElementCount, lastElementChild, firstElementChild, children, nextElementSibling, previousElementSibling, onwheel, onwebkitfullscreenerror, onwebkitfullscreenchange, onselectstart, onsearch, onpaste, oncut, oncopy, onbeforepaste, onbeforecut, onbeforecopy, webkitShadowRoot, dataset, classList, className, outerHTML, innerHTML, scrollHeight, scrollWidth, scrollTop, scrollLeft, clientHeight, clientWidth, clientTop, clientLeft, offsetParent, offsetHeight, offsetWidth, offsetTop, offsetLeft, localName, prefix, namespaceURI, id, style, attributes, tagName, parentElement, textContent, baseURI, ownerDocument, nextSibling, previousSibling, lastChild, firstChild, childNodes, parentNode, nodeType, nodeValue, nodeName

Virtual DOM first level props

props, _owner, _lifeCycleState, _pendingProps, _pendingCallbacks, _pendingOwner

Virtual DOM

  • Diffing algorithm.
  • Batching DOM read/write operations.
  • Efficient update of sub-trees.

Testing components

  • Code is modularized and easy to test
  • ReactTestUtils provide almost everything you need
  • Shallow rendering for isolated structural testing
  • JSDom for integration / behavioral tests

React Native

  • Native development in JavaScript
  • Native UI Views
  • Layout offloaded to a separate thread
  • Performance is top notch

Native Components

  • <span>  <Text>
  • <div>     <View>
  • <img>    <Image>

React is:

  • Simple
  • Fast
  • Testable
  • Flexible

Thank you

Building UIs with React

By Filip Petkovski

Building UIs with React

  • 1,244