ES6 classes with React Mixins (Meteor 1.3+)

TLDR
Combine ES6 classes with (Meteor's) React mixins using react-mixin or by using class inheritance.

Setup

The code examples use Meteor 1.3 (beta) with React added via npm. Meteor 1.3 supports the new ES6 modules which is great in combination with React.

So first make sure you run on the 1.3 beta:

meteor update --release 1.3-modules-beta.11  

Then add react via NPM:

npm install react react-dom --save  

And of course you'll need to add the ReactMeteorData package:

meteor add react-meteor-data  

React Mixins in Meteor

Meteor uses a React Mixin called ReactMeteorData to combine Meteor data with React data. This is a easy way to quickly get started with React. You can read more about how to use the mixin in the official tutorial.

But as you might know the new ES6 classes do not support mixins. And if you (like me) do like to use the new class syntax and the supplied mixin then I have a solution for you.

React.createClass with Mixin (The old way)

Before we had ES6 classes a React class would look something like this:

var TaskList = React.createClass({  
  mixins: [ReactMeteorData],

  getMeteorData() {
    return {
      tasks: Tasks.find({}).fetch()
    }
  },

  render() {
    return this.data.tasks.map((task) => {
      return <Task key={task._id} task={task} />;
    });
  }
});

React.Component (The new way)

But of course we like to use the latest and greatest, so here is what it looks like as a ES6 class:

class TaskList extends React.Component {  
  getMeteorData() {
    return {
      tasks: Tasks.find({}).fetch()
    }
  },

  render() {
    return this.data.tasks.map((task) => {
      return <Task key={task._id} task={task} />;
    });
  }
}

But wait! Where is the mixin? Well, we still need to add it, but we can't use the mixins: [] syntax anymore. Enter react-mixin!

npm install react-mixin@2 --save  

This is a simple library that allows the combination of ES6 classes (and CoffeeScript classes if you like) with React mixins. We simply have to add the mixin after we defined the class:

import React from 'react';  
import reactMixin from 'react-mixin';  
import {ReactMeteorData} from 'meteor/react-meteor-data';

// ... class TaskList definition ...

reactMixin(TaskList.prototype, ReactMeteorData);  

And done! The exact same behaviour as before. Read the documentation on npm to see all of react-mixins features and different ways of applying a mixin.

Class inheritance (Alternative way)

You can also achieve the same result without react-mixin by using inheritance. First we create a class the old way with the supplied mixin:

// react-meteor-component.js
import React from 'react';  
import {ReactMeteorData} from 'meteor/react-meteor-data';

export default React.createClass({  
  mixins: [ReactMeteorData]
});

We can now use this as a base for all of our other classes that require this mixin:

// task-list.js
import ReactMeteorComponent from './react-meteor-component'

class TaskList extends ReactMeteorComponent {  
  // ...
}

The beauty of this approach is that you don't need an extra library and you can get this working in Meteor 1.2.

The future

MDG (Meteor Development Group) is working on a better implementation then the mixin they provided. They have a thread on GitHub describing their plans. But until it's here, this is a nice workaround.

Let me know what you think!