Getting Started with Meteor, React, and React Router

React.js and Meteor.js are great technologies for creating apps for the modern web. A recently announced feature with Meteor 1.2 is official React support. This means developers can now use React for handling client views without even needing to use Blaze or template files.

I have spent a lot of time in the past few weeks learning React and using it in Meteor. Adding additional libraries for React can be troublesome if you aren't familar with the Meteor stack. In this post, I'm going to walk through how to create a Meteor app that uses React and React Router(a popular React routing library). Additionally, you can view the code on Github.

Step 1: Create Your App and Add React

In your terminal run the following command:

meteor create meteor-react-demo

Change your directory to the app.

cd meteor-react-demo

Now that there's an official Meteor-React package, add it to your app.

meteor add react

Finally, move all of your code into folder called client/. It's very important for following steps.

Step 2: Add React-Router Node Package

This step is probably the most complicated part of it all. Since there isn't a package available for React-Router, we'll need to add it with NPM.

Add More Meteor Packages

We need to add a few more packages before we can use Node packages. Run this command:

meteor add meteorhacks:npm cosmos:browserify

Define the Node Packages

Now let's define which Node packages we need in a file called packages.json at the root of the project.

{
  "react-router": "1.0.0-beta3",
  "externalify": "0.1.0"
}

Intialize Our Node Packages

Run meteor to initialize our NPM support. This will create a folder called packages/ which will hold the NPM dependencies.

Run meteor one more time and our depencies will be added.

Step 3: Import React-Router to Meteor

Create a new folder client/lib/. In this folder, we will add two files.

First, create a file called app.browserify.js. This is where will we use require() to import React-Router.

ReactRouter = require("react-router");

Second, create another filed called app.browserify.options.json.

{
  "transforms": {
    "externalify": {
      "global": true,
      "external": {
        "react": "React.require"
      }
    }
  }
}

Step 4: Create a 'Layout' Component

We need to create a 'layout' component in which our views will be rendered. Let's call it App.jsx.

App = React.createClass({
  getInitialState: function() {
  	return {};
  },
  render: function () {
    return (
      <div>
        <h1>Meteor-React Demo</h1>
        <div>
          {/* This is where our view components will be rendered */}
          {this.props.children}
        </div>
      </div>
    );
  }
});

Views that are rendered from our router will be displayed in the code {this.props.children}.

Step 5: Create a View Using Meteor Data

Let's create a new component that displays a list of items. Let's name the file Items.jsx.

Items = React.createClass({
  mixins: [ReactMeteorData],
  getMeteorData: function() {
    return {
      items: ItemsCollection.find({}).fetch()
    };
  },
  getInitialState: function() {
    return {};
  },
  addItem: function(e) {
    e.preventDefault();
    var item = React.findDOMNode(this.refs.input).value;

    ItemsCollection.insert({'content': item});
    React.findDOMNode(this.refs.input).value = "";
  },
  render: function () {
    return (
      <div>
        <ul>
          {this.data.items.map(function (item) {
            return <li key={item._id}>{item.content}</li>;
          })}
        </ul>
        <form onSubmit={this.addItem}>
          <input type="text" ref="input"/>
          <button type="submit">Add Item</button>
        </form>
      </div>
    );
  }
});

Now create a folder at the root directory called lib/ and create a file called Collections.js. We need a collection accessible by both client and server.

ItemsCollection = new Mongo.Collection("Items");

Step 6: Create the Router

Before creating our router, we need to a call require() on another file from React-Router. Add this to client/lib/app.browserify.js:

ReactRouter.lib = {
  BrowserHistory: require("react-router/lib/BrowserHistory")
}

Create a component in a file called Routes.jsx which will hold our routes.

var {
  Router,
  Route
} = ReactRouter;

Routes = React.createClass({
  getInitialState: function() {
    return {};
  },
  render: function () {
    return (
      <Router history={ReactRouter.lib.BrowserHistory.history}>
        <Route component={App}>
          <Route path="items" component={Items}/>
        </Route>
      </Router>
    );
  }
});

This will match the route /items and render our Items component we made. We can easily add more paths here. Read the React-Router documentation to learn more on what you can do with React-Router.

Step 7: Hook It All Together

Delete the original html and js files that Meteor created for us. Create a main.html and add the following:

<head>
  <title>meteor-react-demo</title>
</head>

Create a main.jsx and add this code:

$(document).ready(function() {
  React.render(<Routes/>, document.body);
});

Open your browser and go to http://localhost:3000/items and view the magic.

Remember to check out the demo repo on Github as well as the React Router documentation.

#meteor.js   •   #react.js   •   #react-router