Hacker News new | ask | show | jobs
by waffleau 3475 days ago
This is a complaint I've heard often about React, and usually it's by someone that's never actually tried it (myself included before I first used it). But it's a visceral response. Until you sit down and give it a go, it's hard to believe that we had the separation of concerns wrong. Separation of concerns refers to responsibilities, not languages.

If you're building a static website, sure, you probably don't need React - the old tools and techniques handle that use case well. But if you're building a webapp, something with complex, dynamic client-side behaviour, it doesn't make sense to pretend that CSS, HTML and JS aren't already heavily coupled by the nature of what you're building. React just embraces that idea, rather than pretending it doesn't exist.

The reality of modern apps is that JS is going to transform your HTML and CSS at runtime, and most of the bugs you'll end up tracking down will be related to it being transformed in ways you weren't expecting. React's component model and declarative rendering are far more effective at addressing this problem than any other tool I've tried.

9 comments

Plus React still encourages the traditional separation:

- Model is props/state.

- View is render().

- Controller is everything else (lifecycle, handlers, etc.)

IMHO it's also best-practice to separate view from presentation using CSS modules for component-level styles, and sprinkling namespaced classes here and there so that the component can be styled externally using application-level CSS.

We didn't get the separation of concerns wrong. React is the same we've been doing for 15 years, but we finally understood we had to modularize and encapsulate it to encourage reusability and true separation of concerns.

I'm never going back to traditional code that violates the single-responsibility principle. I'm never going back to manual DOM mutation. Give me modular, namespaced, declarative HTML+CSS+JS and I'll stop using React.

>This is a complaint I've heard often about React, and usually it's by someone that's never actually tried it (myself included before I first used it). But it's a visceral response. Until you sit down and give it a go, it's hard to believe that we had the separation of concerns wrong.

We didn't. And React doesn't change that either. React components are not logic code, they are UI code, and that has always went with view concerns (loop this times, show this button or that button depending on state, etc).

In the Desktop GUI space, where they don't have our HTML madness, do you think their UI components are not using code? Buttons, drop-downs, etc are not appearing by magic, they are created by code that does things like: draw a line of x length and y color, then another perpendicular to that, etc, then loop and draw some stripes, etc. That's the case even in Smalltalk, where MVC was invented. That still matches with "separation of concerns" -- which is about not mixing your BUSINESS logic with your UI code, not about not having code in your UI rendering.

In fact, compared to the classical way (foreach and other kinds of template instructions embedded in template strings, from PHP's Twig to Angular) it's even cleaner, because even though JSX looks like HTML it's actually compiled to Javascript instructions it's not just some ad-hoc language hidden in template tags to be interpreted at runtime.

And separation of concerns also applies to UI elements (encapsulation, re-use, etc) something which "logic free" templates like Mustache and so also miss (or, well, make harder -- of course if you try hard enough you can always fit a square peg in a round hole).

This.

I can't comprehend the very idea of "template languages". Especially in PHP, because PHP itself is a decent template language by design. But even outside - they always evolve the same. They start as a "lightweight" way to avoid putting code into view templates, but then they slowly accrue conditionals, loops, local variables, half-assed tools for defining functions, and before you know, your "no code allowed" template language becomes a Turing-complete and pretty crappy replication of PHP.

And all of that is orthogonal to the main insanity of this whole era - stitching HTML from strings. HTML is a structured tree format, and should be built out as a tree. Gluing strings together is the source of oh so many errors and security vulnerabilities...

Personally, I liked the CL-WHO approach - http://weitz.de/cl-who/.

And after you replicated PHP you come to the conclusion the templating language is as slow as hell. So you think: maybe we would need a compiler so we can cache the templates.

The question ofcourse is: why would people rather use:

  {for item in list}<li>{item.name}</li>{end for}
instead of:

  <?php foreach($list as $item) { echo '<li>' . $item['name'] . '</li>'; } ?>
And I think this goes deep. People are looking for more human ways to express themselves. And PHP is not a very beautiful language. So maybe my first example looks more 'human' than the PHP example.
Note than in PHP you can also rewrite it as:

  <?php foreach($list as $item) { ?>
      <li><?= $item['name'] ?></li>
  <?php } ?>
Or with shortened PHP tags and alternative control structure syntax:

  <? foreach($list as $item): ?>
      <li><?= $item['name'] ?></li>
  <? endforeach; ?>
Which at this point just differs in delimiters (<? and ?> instead of { and }) from the template language.

I don't have an opinion on this "more human way" to express oneself, but it seems that it would connect this case with the reason people seem to prefer curly braces to parenthesis in code too.

And then, to avoid XSS, you'd need to replace that by:

    <?php foreach($list as $item) { ?>
        <li><?= htmlentities($item['name']) ?>
    <?php } ?>
Which is, IMO, the main problem with using PHP (or any other from of plain string concatenation) as a templating language. Escaping everything (and security in general) should be the default, not something that you have to opt into at every turn.
True, though as you note, this is essentially true of any form of plain string concatenation. Dedicated templating languages tend to fail at this too.

Escaping-as-default helps, but people sometimes forget escaping is a function of output context. For example,

  <script>
    frobnicate("{bar}");
  </script>
is a potential vulnerability if the default escaping mechanism for {bar} is one meant for HTML.
you can actually 100% separate HTML from server (or client) side logic if you wish to:

http://stampte.com/

I've never understood why people use templating engines in PHP. I've been an on again off again user of PHP for atleast 7 years now, and I've never understood it for exactly the reasons you outlined.
I've worked some with both WinForms and WPF, and so far I kinda like XAML. And is you're not only working in the windows world, I hear there's a similar-in-spirit JavaScript/HTML framework being used for "new hotness" style applications. Called "electron" or something like that I think?
In short, Electron is a tool for running Node scripts in a real DOM in Chromium (so unlike PhantomJS, it can run things like WebGL).

You can also bundle it to generate distributable desktop applications (e.g. Visual Studio Code, Atom, or the desktop Slack client).

Electron is that thing that bundles the whole web browser with your application so that you can write your usual web code and have it look like a desktop app.
Completely agreed... I've been building web based apps for over two decades now. React is the first framework that feels "right"... there are some things that could be better, It's so much better than what came before. Angular brought me so many WTF moments, I can't even begin to mention them all, even ng2+. With React there's been a handful, usually with a useful error that made sense.

So much effort has been done with React to work with the broader JS community and its' direction as opposed to against it. ES6 class syntax, simple render function components, modules. React doesn't need much to get started, and it's unprescripted enough that just a few tools can round it out, with heavier and lighter options.

I don't want to go back, and frankly, I'd rather have JSX in my JS than go back to weird template DSLs ever again.

> Until you sit down and give it a go, it's hard to believe that we had the separation of concerns wrong.

Well, we had - the whole "separate content from presentation" thing was a cargo cult. Before the recent wave of JS frameworks, the standard website was littered with tons of div elements, almost all of which had zero semantic meaning, and existed only as CSS hooks and/or a hipster replacement for tables. And it was like nobody stopped to ask if all those divs aren't breaking the "separation of concerns" rule - or even if the rule made sense in the first place (it didn't; "presentation" often delivers as much information as "content" itself).

I don't know of any other industry so blinded by fads than web development.

I always thought it was a little silly to religiously persecute script-tags at the bottom of an html page for single-use event hooks and listeners and initialization logic. Instead I was told best practices were to split that one-off code out into another file, bundle it up with a bunch of other unrelated garbage, minify it, and link the whole kit and kaboodle in.

Meanwhile, when you need to go edit the logic operating on some element later, you end up grepping through your code base for ids, classnames, element types, whatever, trying to figure out where that bit of code that operates on that element got to, often several directories in the file structure away from the markup.

> that we had the separation of concerns wrong.

Well, yeah. Forgive me, because I never know, here, if I am talking to my grand-son or my grand-pa, but "Separation of concerns", as an idea, came up when we thought that HTML/JS/CSS was about describing web-sites, for, for example, the NYT vs the WSJ, not for an applet or Swing replacement.

Separating content (including, maybe, semantics too) from presentation (branding, look&feel) makes sense when you are talking about web-pages. I don't even know how the idea transmogrified into a point-of-contention on SPAs.

It's quite funny when you think about it: "Look, Ma! I can build a fully functioning GUI out of type-setting elements and sticks!"

Sorry for not adding anything new to this discussion but that's exactly my thought! Couldn't agree more.
We could extrapolate this trajectory and take a page out of lisp history. Why don't we just let a "web page" be an s-expression delivered by http and run within a sandbox?

If you look at what the racket team has done for their documentation system "scribble", it is pretty clear that we can engineer whatever modularity we require for the purpose at hand given that generality.

This "most effective tool" looks like a fancy way of concatenating HTML strings in JS. :)

Hardly something that can be described as quality software engineering.

That's just silly. Ultimately every tool outputs a 'string' that gets sent to the browser.

What matters is how this happens, and there's a huge difference between React's approach and '<div class="whoops"><?php echo $some_unescaped_dangerous_thing ?></div>'

Or just use Polymer and forget about React.