Creating a container React component

Let’s start by editing our application’s main JavaScript file. Replace the contents of the ~/snapterest/source/app.js file with the following code snippet:

var React = require('react');
var ReactDOM = require('react-dom');
var Application = require('./components/Application.react');

ReactDOM.render(<Application />, document.getElementById('react-application'));

There are only four lines of code in this file, and as you can guess, they provide document.getElementById('react-application') as a deployment target for the <Application /> component and render <Application /> to the DOM. The whole user interface for our web application will be encapsulated in one React component, Application.

Next, navigate to ~/snapterest/source/components/ and create the Application.react.js file inside this directory. All of our React components will have their filenames ending with react.js. This convention allows us to easily distinguish between React and non-React source JavaScript files.

Let’s take a look at the contents of the Application.react.js file:

var React = require('react');
var Stream = require('./Stream.react');
var Collection = require('./Collection.react');

var Application = React.createClass({

  getInitialState: function () {
    return {
      collectionTweets: {}
    };
  },

  addTweetToCollection: function (tweet) {
    var collectionTweets = this.state.collectionTweets;

    collectionTweets[tweet.id] = tweet;

    this.setState({
      collectionTweets: collectionTweets
    });
  },

  removeTweetFromCollection: function (tweet) {
    var collectionTweets = this.state.collectionTweets;

    delete collectionTweets[tweet.id];

    this.setState({
      collectionTweets: collectionTweets
    });
  },

  removeAllTweetsFromCollection: function () {
    this.setState({
      collectionTweets: {}
    });
  },

  render: function () {
    return (
      <div className="container-fluid">

        <div className="row">
          <div className="col-md-4 text-center">

            <Stream onAddTweetToCollection={this.addTweetToCollection} />

          </div>
          <div className="col-md-8">

            <Collection
              tweets={this.state.collectionTweets}
              onRemoveTweetFromCollection={this.removeTweetFromCollection}
              onRemoveAllTweetsFromCollection={this.removeAllTweetsFromCollection} />

          </div>
        </div>

      </div>
    );
  }
});

module.exports = Application;

This component has significantly more code than our app.js file, but this code can be easily divided into three logical parts:

  • Importing dependency modules
  • Defining React components
  • Exporting a React component as a module

You will see this logical separation in most of our React components because they are wrapped into the CommonJS module pattern that allows us to easily require them with Browserify. In fact, the first and the third parts of this source file are related to how CommonJS works and have nothing to do with how React works. The purpose of using this module pattern is to break our application into modules that can be easily reused. Because the React component and CommonJS module pattern both encapsulate the code and make it portable, they naturally work great together. So, we end up encapsulating our user interface logic in a React component and then encapsulate that React component in the CommonJS module. It then can be used in any other module that wants to reuse this encapsulated React component.