In this episode, we finally write our first bit of React!

Note that I’ll assume a basic level of familiarity with React, so if you’ve never used it before I recommend at least going through the official Meteor & React tutorial.

As always, our goal is to replace small pieces of the codebase without breaking the app. So we’ll start by looking for the simplest widget we can find, and replacing it by a React component.

You can refer to the React in Meteor guide for more info on this approach, and in fact I recommend reading the whole thing.

Getting Started

First, you’ll need to install the React package with meteor add react, as well as the React Template Helper package with meteor add react-template-helper

I created a new components directory inside /client/react/. This might change as we start worrying about modules and a better file structure, but it’ll do for now.

Blaze to React

A few things to pay attention when converting Blaze code to React:

  • class becomes className.
  • With JSX, you can’t interpolate code inside quotes. So you might need to remove quotes (i.e. href="{{myLink}}" becomes href={this.props.myLink}, not href="{this.props.myLink}").
  • You can’t reference a global variable right from a Spacebars template, so you’ll need to write a tempalte helper that points to the React component.

The Code

Here’s the React code for the “share your progress” component I work on in the video:

<div class="share-progress-widget">{{> React component=shareProgress chapter=this}}</div>
var getVerb = function (chapterNumber) {
  // pick a verb to introduce a bit of diversity in the prompt.
  // early chapters have more normal verbs, and it gets more crazy at the end.
  var verbs = ['completed','finished','wrapped up','taken care of','dealt with','mastered','gone through','vanquished','dominated','terminated','put to bed','vaporized','decimated','obliterated'],
      vlen = verbs.length-1,
      chaptersCount = 17,
      vindex = Math.floor(chapterNumber*vlen/chaptersCount);  
  return verbs[vindex];
}

shareProgress = React.createClass({

  propTypes: {
    chapter: React.PropTypes.object.isRequired
  },

  verb() {
    return getVerb(this.props.chapter.number);
  },

  tweetUrl() {
    const tweetContent = encodeURIComponent("I've just "+getVerb(this.props.chapter.number)+" Chapter "+this.props.chapter.number+" of @DiscoverMeteor. It's a great way to learn @meteorjs! https://www.discovermeteor.com");
    return 'https://twitter.com/intent/tweet?source=webclient&text='+tweetContent;
  },

  render() {
    return (
      <div className="note share-progress">
        <h3>You've {this.verb()} Chapter {this.props.chapter.number}  <em>{this.props.chapter.title}</em>.</h3>
        <p>Share your progress with the world!</p>
        <a href={this.tweetUrl()} target="_blank" className="button tweet-button simple-button">Tweet</a>
      </div>   
    )
  }
});