This is a great question. IMHO it should be solving a problem for you. If it’s not and you’re happy with another solution I would just keep plugging away.
However for me it’s changed how I develop apps, even when writing Blaze templates (I still do that too!). Its like the difference between using jQuery and Backbone when it first came out. It changes how you think about architecture. I would also highly recommend @sergiotapia’s article on how it changes how you think about it.
[quote="ffxsam, post:1, topic:8100, full:true"]
I thought it was bad practice to mix presentation with code, and React seems to mix them.
[/quote]
IMHO this is something that was very relevant 10 years ago. Writing javascript in your HTML made it hard to edit and hard to figure out when/where things were fired. Using string concatenation to build up DOM fragments in JS had the same problems.
However these days web apps are much different than wiki pages. They’re more similar to native mobile apps. You don’t see iOS/Android using watered down view templates. JSX allows you to use the entire JS language… you don’t have your hands tied with a few handlebars helpers.
Templates are highly coupled to their template scripts. Can you ever use one without the other? It seems we’re just putting them in separate files, decreasing cohesion.
Also not super obvious but the JSX just de-sugars into functions:
<form id='my-form'>
<input type='email' ref='email' />
<input type='password' ref='password' />
</form>
// is transpiled to....
React.createElement("form", {id: 'my-form'},
React.createElement("input", {ref: "email", type: "email"}),
React.createElement("input", {ref: "password", type: "password"}),
);
To each their own. For what it’s worth I hated JSX when I first saw it. Now I love it (once a large template into many smaller components). Pete Hunt explains this better than I can.
[quote="ffxsam, post:1, topic:8100, full:true"]
And what/where is the best place to start learning it, especially in the context of Meteor?
[/quote]
I think these videos are a really nice intro into ‘why/how’ React is different. Egghead also has some nice (free/paid) ones. I’ve also created several open source React Meteor apps that are available to play with. Sashko also wrote a really nice guide on Meteor/React.
[quote="ffxsam, post:1, topic:8100, full:true"]
Basically: why is React so awesome? People talk about its ability to make reusable components, but can't we already do that with Meteor packages?
[/quote]
There’s a lot of cool things about React but the nicest feature is how you conceptually think about a piece of the UI (or component). This makes it easier to reason about and debug. Ideally you want to keep the state out of your component so that it’s essentially a ‘pure function’. Ideally it only has inputs (props) and then outputs a representation of the DOM.
For example it’s very easy to keep this “component” in your head (react pseudo code for non react people) … You can visualize how it will render in your head:
function renderGreeter(props) {
if (props.isBold === true) {
return "<b>Hello</b> " + props.name;
}
else {
return "Hello " + props.name;
}
}
By breaking down the component into a simple mental model you can see how it’s easier to reason about what renderGreeter({name: 'Bob', isBold: false'})
and renderGreeter({name: 'Jane', isBold: true'})
would output.
React encourages you to break down large templates into smaller components so it ends up being this easy. As you can imagine this is very easy to test too!
It’s also recommended to push the ‘state’ upwards in the hierarchy tree so that you can keep your components pure. However this isn’t always do-able. This is what flux does for large apps.
Here’s an example of the ‘typical’ Meteor app with Blaze (contrived but an example of what you have to keep in your head to visualize the ‘output’)
// routes.js
Router.route('/greetings/:name', function () {
this.render('greeterPage', {
data: function () {
return { name: this.params.name }
}
});
});
// greeter.html
<template name='greeter'>
{{#if isBold }}
<b>Hello</b> {{name}}
{{else}}
Hello {{name}}
{{/if}}
</template>
// greeter.js
Template.greeter.helpers({
isBold: function() {
return Session.get('template:greeter:isBold');
}
});
// somewhere else
Session.set('template:greeter:isBold', true);
Typically your data sources are scattered all across the app. This makes it much harder to predict how it will render because the router and session now have to provide the correct data or else the greeter template is hosed. It’s hard to test and even harder to debug if there’s thousands of lines of this. This is still way better than jQuery but it’s not as simple as React.
With React you have many small pieces that make up an app. With things like flux you can easily have hundreds of these ‘pure functions’ in your view which makes it easy to track down and isolate bugs. They’re just taking in params and outputting a DOM representation.
It’s easier to re-use/share these components because there are no other dependancies, in the example above the template expects session to be there and IR to provide it’s data context. React just expects those to props (like params in the first example). I could re-use renderGreeter in any app.
Hope this helps!