What's so cool about React? Am I obsoleting myself by not learning it?

3rd party. Add the manuel:viewmodel package.

Ah cool, it definitely looks easier to maintain. I’m going to give it a shot and integrate it into my markdown editor and see which is easier to use. Thank you

I don’t know much about React either, so I could very well be wrong. But my impression was that Blaze and React did virtually the same thing, in terms of “reactive,” automatic updates to DOM elements that occur when pieces of data they’re bound to (somehow) change.

Is that way off?

1 Like

In my experience changes in -data- are reflected similar to React. Just modify your data and the UI will update.

However when you just need some client side functionality, like:

  • “If this textbox is empty, disabled the submit”
  • “Depending on the radio button checked show either this form or this form”

You need to use either a ReactiveVar, or use jQuery to change (yuck).

1 Like

The true difference between Blaze and React is that Blaze parent templates can’t pass reactively parameters over child templates. But instead forcing to use React with Meteor I hope to see a new Blaze 2 :wink:

8 Likes

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. :smiley: 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!

4 Likes

This is close but not quite how React works. In fact React won’t re-render when the data changes :smiley:.

You would need something else to trigger a render. Calling setState will trigger a render and will re-render all it’s children. Typically this happens in a click handler or something.

In Meteor we have reactive data. However React doesn’t know how to… react to it. We can use Tracker to watch our data and force a re-render. This is essentially what the Meteor mixin does.

Flux is an architecture that allows the view to emit an ‘action’, a ‘store’ updates it’s data if needed and calls a general ‘change’ event. The app can listen for that change and re-render if it receives the event (in Meteor we track a collection and fire a flux ‘change’ event on change).

Also worth noting, Blaze will only re-render the part of the DOM that the data is bound to. React will re-render the entire sub-tree. This makes it easy to not worry about other parts not updating.

Not quite. You’re maybe mis-understanding the nature of tight coupling. Some of us frequently use the template html or the template script without the other. A few instances just off the top of my head…

  • scanning html files for ids and classes and extracting test/validation commands
  • converting from html to jade or vice versa to onramp junior developers
  • using the script without the html to do boundary testing;
  • using the html with a secondary script to generate email templates;
  • overloading stylesheets with user-defined accessibility stylesheets;
  • overloading stylesheets with media specific stylesheets (print to pdf)

For those of us who are regularly doing these kinds of activities, the HTML/JS/CSS is actually a loosely coupled architecture.

That being said, your point is well taken. For most people starting out, it may certainly seem to be tightly coupled. I’d suggest that this is an artifact of the tools we use. For those folks who have programmed in Visual Studio or XCode, they’ll remember that it’s common pattern to have a meta/context bar that contains structure, events, and styling. MVC. HTML/JS/CSS. Globbing everything into a single file is one way to increase cohesion between files in a component; another is to build tools that move and edit the files around as a unit.

Which is exactly what some of us have been doing with the StarryNight refactoring tools and the Atom meteor-api package.

2 Likes

Checkout the React-ive Meteor app/repo and the readme for a more complicated app.

The Flux leaderboard shows how to use flux for more complex apps.
(looking to create a flux branch for Reactive Meteor soon)

These are distilled out of my production apps that i’ve made recently. I’ve written several thousand lines of production React code and have ironed out a lot of Meteor specific issues. I’m migrating all of my other apps gradually as bugs pop up, they get replaced with React + flux.

I also wrote a tutorial on Unit Testing React in Meteor

3 Likes

with this, i can still use my Blaze knowledge in react :smiley:

1 Like

I love the sound of React but im still put off by JSX.

It mangles HTML and javascript together in a way which often looks like a mess.

For example in manuel’s post in the react example we see this.state.text.length === 0 Why are we running javascript inside a template? Isn’t that unmaintainable? Doesn’t this go against everything templating/views stand for?

In the same example the blaze helper buttonDisabled makes the template a lot easier to manage. I don’t need to rely on the implementation details of why the button should be disabled.

Blaze just looks closer to separating design and logic. You can write documentation for helpers etc and then hand it to a designer who only has to touch the templates.

Can react be used without JSX?

@ahref I am at the tail end of a huge project that uses Blaze + Meteor. I just started a new one with React + Meteor. JSX is awesome! My code never looks mangled or like a mess. In React you break everything down into small components and it makes your app much easier to test and reason about. Every time I have to work in the app I’m just finishing I wish I would have done it in React. Yes, you can use React without JSX but it makes markup more complex

1 Like

I just read a well-written overview of React on Tuts+, and it gave me a good (though very high-level) view of how it works and why people find it so compelling:

I’m actually in the middle of a React.js tutorial (it’s written for an audience of “people who know just enough jQuery to get by” and it’s pretty easy to follow, but it may be overly simplified for a lot of you):
http://reactfordesigners.com/labs/reactjs-introduction-for-people-who-know-just-enough-jquery-to-get-by/

I agree that people (like myself, until I read that first tutorial I linked to) who are put off by the thought of mixing presentation layer (HTML) and code may be jumping to conclusions too quickly without giving it five minutes to learn a bit about it first.

But I disagree with the notion that separation of the two is no longer relevant. I think the Tuts+ author put it well when he said (I’m summarizing) a strict separation of those concerns (a la MVC) is (still) appropriate for small- to medium-sized apps, but for huge, sprawling & distributed web apps (e.g. Facebook), it makes a lot of sense (at least, in client-side code) to think in terms of individual components (like a Tweet box, or a playlist, or an email inbox, or a form) and to keep the HTML template and the DOM-manipulation code together, the way React does. (I still think separation of code and HTML, like most MVC frameworks enforce, is still the way to go with server-side frameworks, like Yii, Django and Rails. I can’t think of any good reason to mix HTML and PHP together, for example).

Then maybe I’m not understanding React as well as I thought I did (I’m at the beginning of the tutorial). And, if it doesn’t do that stuff automatically, why is it called “React?” I thought one of its major selling points was that it automagically managed DOM updates without you, as the developer, having to manually write event handlers (like in Backbone) or data bindings (like in Angular), similar to the way Meteor is so awesome with reactive updates behind the scenes.

I’m all about using the best tool for the job. React sounds very cool, and I’m sure all the people talking about it can’t be wrong, but my main priority with React is figuring out how it could be most useful to me, today. I have no plans to build anything as large as Facebook anytime soon, so if doesn’t have quite as many compelling benefits for small/medium-sized apps, then I’m not sure I want to invest the time to learn it.

I’m completely sold on Meteor as an upgrade to the way I’ve been building server-side and client-side web apps for the past decade+. But what I REALLY want to know about React is, how can it be used with Meteor (in specific use cases; I’m aware of the meteor-react package, but I don’t know much about it)?

And what compelling features does React offer that Meteor doesn’t? Can they both be used together without having to jump through too many hoops to get them to integrate play nicely with each other? If I would have to go back to manually writing data-binding code to use React, when Meteor manages that for me, I’m not sure how interested I’d be.

1 Like

@ahref
JSX is optional and is there mostly as a convenience for developers. You don’t have to use it. (from what I can tell - I haven’t used React yet. I’m still investigating whether its worth the effort to learn or not, like you all).

Please, someone correct me if I’m wrong here. I’m just trying to see if I’m understanding React’s design philosophy.

From what I can tell, the reason they couple the JSX template together with the JavaScript that controls it is that, in React, the primary entity is the Component, which represents a UI component, like an inbox, or a playlist, or a login form (and this is partially what people mean when they talk about creating custom components in React).

Also from what I can tell, the React framework authors’ reasoning for coupling the view code (JSX) and the Component that renders it together is that, in a giant web application (they created React for Facebook, after all), there are so many different little UI components, that the MVC model doesn’t make sense anymore - keeping the templates separated from the controllers and models starts to become more of a hindrance than a beneficial design pattern in such a large front-end application, right? If that’s correct, I can see how that might make sense for large front-end applications.

If I’m way off or if I’ve gotten any part of this wrong, please steer me in the right direction. I don’t want to invest weeks learning React if it’s not right for me, but I don’t want to miss out either, if it is. :wink:

2 Likes

It’s most likely my lack of a better explanation! It does automatically update but only when calling setState or force rendering.

Since it’s just the view layer it doesn’t include or force you to use a reactive/observable data source. Instead it uses normal Javascript objects, arrays, etc…

For instance to make a counter increase with local state here’s what would happen

In Blaze:
setup template: Counter: {{getCount}}
setup js helper: return Session.get('count')
on button click handler, Session.set('count', Session.get('count') + 1);
view automatically updates

In React
set initial state : {count: 0}
setup template/render: Counter: {this.state.count}
on button click handler: this.setState({count: this.state.count + 1})
view automatically updates

With both Blaze and React you’re declaratively describing how the view should look instead of imperatively saying how to do it (like jQuery). With the React example the state is locked into just that component (unless it passes it down to a child).

When you want to auto render with database collections you need to use the mixin so that it will auto render on change (you could do this manually but it’s verbose).

Does this help answer your question?

It’s really about simplicity and easier maintainability. Blaze is great too but is easier to make a mess with. It doesn’t force you to use good habits.

Also the React community focuses a lot on making things maintainable… not so much here in the Meteor community (more is focused on finishing faster or less keystrokes).

Meteor offers a lot more than React, as Meteor is the server, client, etc… using React just swaps out Blaze for React. Once you learn how data flows through React they play together really nicely!

2 Likes

Ok, yeah - I think I get it now. When you said that, I remembered reading in that Tuts+ overview article that React.js creates some sort of virtual DOM, and that Components are organized into a top-down, tree-like hierarchy, and that when you have a piece of your UI that you want to be updated dynamically, you just (declaratively) tell the top-level Component to re-render, and it takes care of updating all the dynamic, data-driven pieces of your template by recursively telling all of it’s child Components to re-render. That makes sense.

It also makes sense that, like you said, being a client-side only framework, it’s not typically accessing data that’s external to JavaScript (even data received through an API would likely be in JSON, or accessed through JavaScript’s XML API, at worst [does JavaScript have an XML API? I’m not sure]).

I really like the declarative approach better when it makes sense.

Yeah, I realized early into the Discover Meteor book (I’m only like half-way through it) that the choice not to impose “convention over configuration,” like some frameworks do, would be nice in some ways, but that it would require that you impose your own structure on your applications. And that requires a lot of discipline. But there’s always a trade-off. Frameworks that impose a lot of conventions on you do free you from having to make decisions about everything, but then they also take away your freedom to make choices about some things you might want to make your own decisions about (but that’s what plugins are for :wink: ).

That sounds good. It might work well for me, too, because I’m just now learning the most basic fundamentals of Meteor. I haven’t even begun to read through all the Blaze documentation yet.

But, how well do they interact, Meteor and React? I hear what you’re saying about replacing Blaze with React, but is it an actual drop-in replacement? Or do you have to make tweaks to Meteor’s configuration, or adjustments to your workflow to integrate them together into an app?

@thebionicman I’m glad that makes more sense!

It’s essentially a drop in. You just add it with meteor add react and then create a .jsx file. If you’re not using a router then you’ll have to mount the topmost component with React.render into a div and from there on it takes care of itself.

Session pretty much doesn’t get used as you’ll typically use the component state instead. In order to use the database/minimongo you can use the mixin and getMeteorData to auto-update/render. For large apps you can even use flux… but that’s another post :wink:

Reaktor is a great facade on top of FlowRouter for easy React routing.

You can even render Blaze templates into React and vice versa (I do this for certain packages like DataTables which is a lifesaver). If you don’t want any Blaze you’ll be able to drop it easier in Meteor 1.2 (I don’t think that’s released currently)

I’ve also open sourced a React + Meteor boilerplate that you could use to clone and get started. It might have a little too much for day 1 but you could always just edit the both/pages/Home.jsx page and then explore when things make more sense.

This also has browserify setup so you can include NPM packages/components easily.

For more specific Meteor tutorials checkout this one:
http://tutorial-viewer.meteor.com/tutorial/0/react

2 Likes

Thanks for the reply.

Do you have any response to my other questions?

Particularily I’m interested in why this.state.text.length == 0 floating inside HTML is suddenly OK because react is involved.

I get that it is a simple example but it resembles the old days of PHP where you’d drop in and out of the language with <? ?> and use echo statements.

I know its not the same because react tracks state etc but readabilty / code wise it looks the same.

Would you use such a style in a full application?

Ultimately it just appears to be a mix of concerns. Logic within templates should be a minimum right?

As for JSX it looks like it would get unwieldy with a larger component. For example a product information card. I’ll look through some examples but I guess I want the HTML in a different file away from the JavaScript to allow designers an easier time?

1 Like

Whoa, this thread really blew up! I’m glad it sparked such a discussion, and I appreciate the time everyone took to reply. I’ll have to revisit this when I have some spare time, hit the links, and post a response. Thanks!

1 Like