Meteor Blaze vs Meteor React

A Simple Comparison

Steven Scaffidi
4 min readFeb 23, 2016

Let me start out by saying that I am no Meteor expert. I’m continuously learning more everyday. The purpose of this article is to make a simple comparison of React and Blaze in the context of the Meteor framework. I’ll do that by making some comparable components that achieve the same results. For React, I’ll assume I’m working in Meteor 1.3. So let’s start.

Here is a Blaze Template:

<!-- contents of sample-template.html -->
<template name="sampleTemplate">
<div class="hello-world">
Hello {{world}}
</div>
</template>

In the above example, I included one helper. So let’s define it in our JS file.

//contents of sample-template.js
Template.sampleTemplate.helpers({
world() {
return 'World!';
}
});

Obviously the above is as simple as it gets. So let’s see what this looks like in React.

//contents of hello-world.jsx
import React from 'react';
const HelloWorld = ({world}) => (
<div className="hello-world">
Hello {world}
</div>
);

The HelloWorld React Component above is actually known as a stateless function. A stateless function can accept properties; but as the name implies, the component does not handle state. Whenever possible, this is actually React’s preferred method of developing components.

In an ideal world, most of your components would be stateless functions because in the future we’ll also be able to make performance optimizations specific to these components by avoiding unnecessary checks and memory allocations. This is the recommended pattern, when possible.

Before we move on, also take note that class is now className. Even though JSX might look like HTML at times, it is in fact JavaScript. So it makes sense that you can’t use HTML attributes like class and for and instead have to use className and htmlFor

So how is {world} defined in our example above. Well that happens when we actually want to render it. Our HelloWorld component has one property which is world. So we just define that property like below.

<HelloWorld world="World!" />

So how do we actually render the template and the component respectively. Let’s assume that we are using Flow Router. For Blaze, we are using BlazeLayout. So in Blaze, let’s render our template. First create a layout.

<!-- contents of layout.html -->
<template name="layout">
<div>
{{> Template.dynamic template=main}}
</div>
</template>

Then in the router let’s actually render our template.

//contents of router.js
FlowRouter.route('/', {
name: 'home',
action() {
BlazeLayout.render('layout', {
main: 'sampleTemplate'
});
}
});

Now let’s do the same in React. Instead of using BlazeLayout, we’ll use the NPM package react-mounter. Let’s create a layout.

//contents of layout.jsx
import React from 'react';
export const Layout = ({content}) => (
<div>
{content}
</div>
);

Notice this is another stateless function acting as our layout. Now let’s render our component.

//contents of router.jsx
import React from 'react';
import {mount} from 'react-mounter';
import {Layout} from './layout.jsx';
import {HelloWorld} from './hello-world.jsx';
FlowRouter.route("/", {
action() {
mount(Layout, {
content: (<HelloWorld world="World!" />),
});
}
});

That’s it. In the above examples, Blaze and React are very similar. So let’s dive a little deeper and create a component in React that has state. Let’s start out with Blaze again. We’ll create a simple form and then we’ll show the user an alert with their input when they submit the form.

<!-- contents of sample-form.html -->
<template name="sampleForm">
<form>
<input type="text" name="userInput" />
<button type="submit">Submit</button>
</form>
</template>

Now let’s handle the action of submitting this form.

//contents of sample-form.js
Template.sampleForm.events({
'submit form': function(event,template) {
event.preventDefault();
const userEntered = template.$('[name=userInput]').val();
alert('You entered: '+ userEntered);
}
});

Let’s do the same in React.

//contents of sample-form.jsx
import React from 'react';
class SampleForm extends React.Component {
handleSubmit(event) {
event.preventDefault();
const userEntered = this.refs.userInput.value;
alert('You entered: '+ userEntered);
}
render() {
return (
<form onSubmit={this.handleSubmit.bind(this)}>
<input ref="userInput" type="text" />
<button type="submit">Submit</button>
</form>
);
}
}
export default SampleForm;

That’s it. Now let’s pretend that we want to render these things right below our previous template/components. Let’s do Blaze first.

<!-- contents of sample-template.html -->
<template name="sampleTemplate">
<div class="hello-world">
Hello {{world}}
</div>
{{> sampleForm}}
</template>

And in React.

//contents of hello-world.jsx
import React from 'react';
import SampleForm from './sample-form.jsx';
export const HelloWorld = ({world}) => (
<div>
<div className="hello-world">
Hello {world}
</div>
<SampleForm />
</div>
);

That’s it. Here is an example of the repo we made using Meteor 1.3 and React. So the point of this comparison is just to point out some similarities to using Blaze and React in the context of Meteor. I’m not proposing using one over the other (even though it’s clear the Meteor community is moving toward React). My purpose was to present something that was dead simple. So even though these patterns are basic they can be expanded upon. For Blaze, the go to source is guide.meteor.com. React has a number of resources; but in the context of Meteor, I would highly recommend Sacha’s video series in switching a Blaze app to a React app. Hope this was helpful for some trying to make the switch from Blaze to React.

Update: At Foodfully we actually make use of both React and Blaze to make our application. Check us out at http://foodfully.com/

--

--

Steven Scaffidi

Full Stack @reactjs @reactnative @feathersjs @expressjs ReasonML developer | Tulane MBA @freemanschool | Husband | Rescue Dad