One of our teams at Boltmade was recently tasked to build a front-end JavaScript application. There are plenty of frameworks to choose from, and while we have experience with many of these options, we decided to give Facebook’s React library a try on the merits of its simplicity and re-usability.

React Components

We found the strength of React to be in its use of dynamic, highly-modular components. Each component is a JavaScript class that models a particular view such as a drop-down or a navigation bar.

var ItemList = React.createClass({
  getInitialState: function() {
    return {
      items: [
        {id: 1, name: "Option 1"},
        {id: 2, name: "Option 2"}
      ]
    };
  },

  removeItem: function(id) {
    var updatedItems = this.state.items.filter(function(item))
      return item.id !== id;
    });

    this.items.setState({items: updatedItems});
  },

  render: function() {
    var items = this.state.items.map(function(item) {
      return (
        <ItemEntry entry={item} removeItem={this.removeItem}/>
      );
    });

    return (
      <div className="container item-list">
        {items}
      </div>
    );
  }
});

var ItemEntry = React.createClass({
  render: function() {
    return (
      <div className="item" item-id={this.props.item.id} onClick={this.clickRemove}>
        {this.props.item.name}
      </div>
    );
  },

  clickRemove: function(e) {
    this.props.removeItem(e.target.getAttribute('item-id'));
  }
});

Components have state and property variables that can be accessed using this.state and this.props. A component’s state consists of mutable data that it can set and change. If a parent component needs to make a child component aware of its state, the parent can pass down this data as immutable properties to its children.

React is set up for a one-way flow of data down a structured tree of components. Only one component takes ownership of state data. In our example we are giving each ItemEntry an item property from its parent’s state that will be accessible to the child.

Updating State

Since data is only communicated in a single direction, from parent to child, it is the responsibility of the component that owns the state data to perform an update. React has its own cross-browser event system for capturing and responding to events. React’s synthetic events are W3C compliant and as a benefit of this, even older browsers like IE8 have access to many HTML5 events.

The best way to demonstrate this event handling in action is to look at what happens when a component informs its parent that it needs to update.

When an ItemEntry component is clicked, it triggers the onClick event that fires its removeItem handler. This handler, calls the parent removeItem method that was passed down to the ItemEntry as a function reference property. Once the state is updated in the parent component, all of the parent and child views must re-render to reflect this change.

To accomplish this, React uses an in-memory virtual DOM to efficiently modify its views whenever a component’s state changes. Components have a render method that returns a description of the new state of the DOM. It creates a new virtual DOM subtree which it diffs with the old virtual DOM to determine the minimal set of changes that need to be executed. It then finally interacts with the actual DOM and quickly updates it to reflect these changes.

JSX Syntax

In our render method we are using React’s XML-like JavaScript syntax extension called JSX to structure the view. JSX allowed us to mix HTML elements and React components in a structured hierarchy. In our example above we are using the ItemEntry React component within the item list HTML container. While JSX is completely optional for using React, we found it useful in describing our views.

React has an in-browser transformer for JSX that they suggest to turn JSX into native JavaScript for development mode. In production, we use a Browserify transform to prepare all of our JS ahead of time.

There is also an excellent Google Chrome extension, React Developer Tools, that adds a new React tab to your dev tools for inspecting React components directly and accessing their state and properties.

Component Lifecycle

React components have built-in functions that are triggered at specific moments in a component’s lifecycle.

componentWillMount and componentDidMount offer hooks to make any changes before and after a component is first rendered.

componentWillUpdate and componentDidUpdate are similar methods used to respond to a change in a component’s state, and or properties both before and after it re-renders.

If for some reason a component should not re-render when its state or properties change, then there is another lifecycle hook componentShouldUpdate that will conditionally allow or prevent a re-render of the component based on the boolean return value of the method.

Reactions

We were very pleased with our results using React. It allowed us to create lightweight views that separated our UI into a logical structure of components. The speed and ease of React’s system of rendering eliminated nearly all of our direct DOM manipulation.

Having never used React before, we never encountered any major stumbling blocks as we became familiar with the library and it was very easy to pick-up.

React is definitely a library that we will keep in our toolbox for future projects.