Latest

An Introduction to React.js

React is a JavaScript framework for building reusable UI components. These can easily have their state and properties managed and kept in sync with other components that share the same data. This data binding and state management is very conducive to building dynamic applications.

Here at Instrument, we've recently begun building projects using React and have found it to be really useful and fairly quick to learn.

This introduction covers the very basics of React. More advanced information regarding functionality within other addons or enhancing React with nodeJS and Browserify can be found within the React documentation.

Key features


Performance

React performs extremely well due to managing a virtual DOM rather than watching and updating the browser's actual DOM on the fly. Because the virtual DOM is just data rather than rendered content, React is able to efficiently determine what pieces have changed. Once changes are made, the updated DOM can be re-rendered efficiently using features like `requestAnimationFrame` to ensure optimal performance.

JSX

Another key feature is the XML-like JSX language. While React can be used without JSX, it's a very useful shorthand for writing markup for components and binding events.

The React docs provide a very clear example of the differences between writing a component in JSX and JavaScript. First, an example of how to construct and output a DOM element inside a component's native render method:

render: function() {
  return React.DOM.a({
    href: 'http://facebook.github.io/react'
  }, 'React');
}

This code renders a standard anchor tag that looks like:

With JSX, to render that same anchor tag, you can instead write the following code inside of a component's native render method:

render: function() {
  return React;
}

Notice that the JSX version looks just like standard HTML. However, the JSX interpreter is not just changing the `innerHTML` property of any DOM element to accomplish this. It's merely a representation of the actual DOM node to be rendered. This allows for passing properties, state, and event bindings to JSX objects. For example:

clickHandler: function() {
  console.log('Hello');
},

render: function() {
  return React;
}

While this method of event binding looks it's being done on an element inline, JSX is merely an interpreter that will make a reference to a real DOM node. There are a variety of native normalized event handlers that can be bound to components. These don't actually get rendered into your HTML. A full list of React's supported events can be found here along with information on binding other events beyond the ones provided.

If you're comfortable with using JSX syntax inside of your code, it's a fantastic and speedy way to write your components.

One-way data flow

In a more traditional MVC framework, different views would be able talk to each other which can lead to difficulties keeping data in sync as an application increases in size and complexity. React is built to support data only flowing downstream. The intent is to have components be immutable and only listen to data coming from upstream rather than to each other. This makes it much easier to create canonical data sources that stay in sync across any components paying attention to them.

When data somewhere upstream is updated, any components making use of that data will automatically re-render to reflect any changes. To help support this style of data binding, React promotes using a methodology called Flux as an alternative to MVC. An overview of Flux and information on how to architect your application can be found in the React documentation.

Demo

Let's use some of the previously discussed concepts in building a simple input form that updates another component as it's being used. The goal of this demonstration will be to show how state updates, data binding, and events can operate.

First steps

First, we'll create a component to house our form input and a DOM element that will reflect the contents of the input. Note that we'll be using JSX, and any adjacent JSX components must be grouped within a parent DOM element such as a `<div>` tag.

var InputDemo = React.createClass({
  render: function() {
    return 
; } });
Creating another component

Now, this code won't actually work without defining a `ContentArea` component first. Our code then becomes:

var InputDemo = React.createClass({
  render: function() {
    return 
; } }); var ContentArea = React.createClass({ render: function() { return
; } });
Creating state

This still isn't terribly interesting. Nothing is going to be rendered to the page beyond an empty input. Let's see how we can manage some state within our components first.

var InputDemo = React.createClass({
  getInitialState: function() {
    return {
      hasContent: false,
      content: ''
    }
  },

  render: function() {
    return 
; } });

We now have an initial state, but how do we update it? What can we use it for? How about a CSS selector that allows us to style an active or inactive state. The state of the content itself can eventually be used for our `ContentArea` component.

var InputDemo = React.createClass({
  getInitialState: function() {
    return {
      hasContent: false,
      content: ''
    }
  },

  render: function() {
    var classes = this.state.hasContent ?
      'active' :
      'inactive';
    return 
; } });

This is a very basic example of how you can use state within a component. In this case, the wrapping `<div>` in our component gets assigned a class based on the state. Inside JSX, ternary operators must be used instead of if/else statements.

Changing state

Now that we are using state to affect rendering, we need to be able to update that state. This is done with a native `setState` method. Let's trigger that method through our input detecting an `onChange` event.

var InputDemo = React.createClass({
  getInitialState: function() {
    return {
      hasContent: false,
      content: ''
    }
  },

  changeHandler: function(e) {
    this.setState({content: e.target.value});
    this.setState({hasContent: this.state.content !== ''});
  },

  render: function() {
    var classes = this.state.hasContent ?
      'active' :
      'inactive';
    return 
; } });

When a change event fires on the `<input />` field, the state of `InputDemo` is set to `true` if the input has content and `false` if not.

Passing data

Now we have some rudimentary state but we still need to get data into our `ContentArea` component. In this case, we're going to pass in the state of our content.

render: function() {
  var classes = this.state.hasContent ?
    'active' :
    'inactive';
  return 
; }
Using the data

Inside of the `ContentArea` component, we can now access an internal property called `content` by using `this.props.content`. Because this property is being inherited from somewhere upstream, it has the potential to change. When a property or state of a component updates, it is automatically re-rendered. This is how our content will be able to update as we type.

var ContentArea = React.createClass({
  render: function() {
    return 

{this.props.content}

; } });
Putting it all together

Here's all of our tiny app put together in one place. The last thing to do is to call React's `renderComponent` method and pass it both our parent `InputDemo` component and a DOM element in the page that will render all of our React code. Let's assume we're rendering to `<body>`. Don't forget to include the `JSX` comment block. This is required for JSX parsing.

/** @jsx React.DOM */

var InputDemo = React.createClass({
  getInitialState: function() {
    return {
      hasContent: false,
      content: ''
    }
  },

  changeHandler: function(e) {
    this.setState({content: e.target.value});
    this.setState({hasContent: this.state.content !== ''});
  },

  render: function() {
    var classes = this.state.hasContent ?
      'active' :
      'inactive';
    return 
; } }); var ContentArea = React.createClass({ render: function() { return

{this.props.content}

; } }); React.renderComponent(, document.body);

Final Notes

Now with a basic understanding of how React operates and its purpose, you should be able to get rolling on building your own projects. Again, React's site provides all the information you need to setup a project and begin coding.

Related