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


#1

Should I learn React? Is this one of those things where I’ll get left in the dust of obsolescence if I don’t learn it? I still can’t figure out what the appeal of React is. I thought it was bad practice to mix presentation with code, and React seems to mix them.

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? And what/where is the best place to start learning it, especially in the context of Meteor?


#2

React is a new rendering method. It is like a game engine to render DOM to UI in frame.
Unlike Blaze and Angular it is a complete new thinking. So far can not say it is better or not at least it is not mature.
To develop a new GUI model, a new theory is required. React is not mature in theory today.

But React may have potential to apply GPU to speedup rendering in the future.
React removed data-binding completely. React still faced the reusable component problem.
React does not solve the problem of big HTML app, ie. 1000 line HTML code (not javascript).


#3

I don’t think it’s a good idea to type up a large reply when this does such a magnificient job of explaining why React is so exciting.

http://reactfordesigners.com/labs/reactjs-introduction-for-people-who-know-just-enough-jquery-to-get-by/

Set aside 30 minutes, and read that article and really understand and internalize what you’re reading. Don’t just copy and paste it.

This image is why React makes sense in a nutshell:

http://reactfordesigners.com/images/labs/jquery-style-vs-react-style.png


I’m still not using it in my Meteor apps though, I haven’t found a nice way to structure things in a way that makes sense and I’m not totally sure it’s kosher to use in production yet (in Meteor).


#4

You could look into Sideburns: https://github.com/timbrandin/meteor-react-sideburns

Blaze formatting for React.


#5

I’m a huge fan of using react and meteor together. I don’t know what would stop you from using it in production.


#6

Mainly documentation and ‘beaten path’ examples. :wink:


#7

Meteor’s own path had not been neither documented, nor beaten up until recently, but look where it got us all :smile:


#8

That’s JQuery vs React, let’s compare Blaze vs React:

React

var TweetBox = React.createClass({
  getInitialState: function() {
    return {
      text: ""
    };
  },
  handleChange: function(event) {
    this.setState({ text: event.target.value });
  },
  render: function() {
    return (
      <div>
        <textarea onChange={this.handleChange}></textarea>
        <button disabled={this.state.text.length === 0}>Tweet</button>
      </div>
    );
  }
});

Blaze

Template.TweetBox.onCreated(function(){
  this.text = new ReactiveVar();
})
Template.TweetBox.helpers({
  buttonDisabled: function() {
    return Template.instance().text.get().length === 0;
  }
})
Template.TweetBox.events({
  'change textarea': function(event) {
    Template.instance().text.set(event.target.value);
  }
})

<template name="TweetBox">
  <textarea></textarea>
  <button disabled={{buttonDisabled}}>Tweet</button>
</template>

They aren’t that different when it comes to developer experience. They use very different techniques to update the screen but you’re coding the same way. You still have to have an event handler for the input change, and you still have to manually update an object that holds the state of your app.

But I’ll give you that it’s easier to write messier code with Blaze than React.


#9

This is exactly the way I’m working at the moment. It’s pretty good.


#10

May I interest you in a different way? :blush:

Template.TweetBox.viewmodel({
  text: '',
  buttonDisabled: function(){
    return this.text().length === 0;
  }
})

<template name="TweetBox">
  <textarea data-bind="value: text"></textarea>
  <button data-bind="disabled: buttonDisabled">Tweet</button>
</template>

#11

Uncaught TypeError: Template.TweetBox.viewmodel is not a function

http://meteorpad.com/pad/N46wgLQHFkZiDjP3r/Leaderboard


Is viewmodel built into Meteor or a third party package?


#12

It’s a third party package.


#13

3rd party. Add the manuel:viewmodel package.


#14

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


#15

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?


#16

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).


#17

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:


#18

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!


#19

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.


#20

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.