Hacker News new | ask | show | jobs
by ageofwant 3203 days ago
JSX is not HTML. You are not writing HTML when you write JSX, you are writing Javascript. You are using a more convenient syntax to generate the virtual dom. All this hand wringing, navel gazing cargo-culting JSX gonna eat my baby bs is unnecessary. The PHP/html templating lessons of yonder simply does not apply.
1 comments

> You are not writing HTML when you write JSX, you are writing Javascript.

And why the hell you have to write code in JS that will be ultimately represented as HTML? Is it because it simplifies some processes for the React's VDOM implementation? Don't you make your life harder in order to make React's life easier? If you say it's because you get template code linted in the same way as a regular JS code, I say that other frameworks also validate the templates doing AOT compilation.

The problem with templates is, ultimately, they end up re-implementing a lot of whatever programming language they're built in. Things like `{{%if}}`, `{{%for}}`, helpers, etc. are simply ways to write code in a template. Which is fine on the surface; these are features that meet the requirements of creating a UI, it's not like we'd want a templating system without them.

The issue is that now you have a ton of code (it is code, btw) living in a templating language that probably doesn't have as good of debugging, documentation, performance, encapsulation, composition, etc. as the underlying language it's using to process the template. It's up to the maintainer of the templating system to handle re-implementing that, and if you end up in a situation where it doesn't actually meet your requirements, you either have to add these basic language features yourself or start from scratch.

That's why things like React and Hiccup (and even more advanced, something like Racket), etc. have gained huge popularity and mind share: instead of re-implementing the programming language in a template system to show HTML, let's implement an embedded DSL to conveniently write HTML.

Then suddenly we get away from managing gnarly data dependencies, stack traces through templating systems, and writing stuff like this:

    {{%if medicare_eligible %}}
    <div>Here's some discounts!</div>
    {{% else %}}
    <div>You gotta pay full price</div>
    {{/if}}

    // ...
    templateSystem.create('template.hbs', { medicare_eligible: user.age >= 65 }

To just:

    if (user.age >= 65) {
      return <div>Here's some discounts!</div>
    } else {
      return <div>You gotta pay full price!</div>
    }
Once you are writing in an embedded DSL, you no longer need to worry about re-implementing all of the constructs of the underlying language; it's laid there at your feet.

Furthermore, by modeling your view as simple functions and data, you get all the features of data manipulation (huge productivity gain; don't need to write to rewrite or relearn `map`, `reduce`, `for`, serializing, etc.) and function composition (this is HUGE. I could write a whole blog post on this).

You are comparing with Handlebars templates, which bring an overhead on top of the HTML structure itself - in this case it makes sense to use JS instead of the custom syntax. But compare with Thymeleaf/Angular/Vue like templates - these are natural templates, you work only with HTML, controlling behavior using attributes which are part of the HTML.

> The problem with templates is

But the good part is that with natural templates you see stuff in a perspective and in a more plain/readable structure. It's like coding something in Assembler/low-level vs in Java/C#/JS.

What's natural about them? Controlling behavior through attributes is one of the silliest ideas invented, IMO.

I've used Angular - frankly, its template syntax is horrendous. I had to learn a ton of new semantics (`whatever` `(whatever)` `[whatever]` `#whatever` all have different execution contexts), and ultimately they've re-implemented most of JavaScript and* Angular inside of this HTML template syntax. Vue is about the same AFAICT. There's a lot of good in these frameworks, but templates is not one of them.

I don't understand your comparison to Assembler. How is this more like Assembly than a high level language?

React:

    return (
      <div>
        <button onClick={onSave} />
        {heroes.map(hero =>
          <button onClick={deleteHero(hero)}>{hero.name}</button>)}
        <form onSubmit={onSubmit}> ... </form>
      </div>
    );
Angular template:

    <button (click)="onSave($event)">Save</button>
    <button *ngFor="let hero of heroes" 
    (click)="deleteHero(hero)">{{hero.name}}</button> 
    <form #heroForm (ngSubmit)="onSubmit(heroForm)"> ... 
    </form>
Think of it like this: in templates, you write a string that will be tokenized and compiled into an AST, which then get interpreted by the host language. In React (or whatever other vdom-building library you want to use), you generate the AST using functions in the host language. This is simpler, more powerful, AND (in this day and age) easier to use.

Here's something neat about the React example, too: since it's a pure function, it can easily be unit tested without rendering to a DOM or doing some weird string stuff.

>Angular/Vue like templates - these are natural templates, you work only with HTML, [...] the good part is that with natural templates you see stuff in a perspective and in a more plain/readable structure

If you're using adjectives like "natural" without qualifying it with "in my opinion", it means you don't really understand the higher meta level discussion.

It is not objective fact that embedding a Turing Complete programming language inside of HTML via custom attributes such as Angular "ng-xxx" and Vue "v-xxx" is "natural". Many find it quite unnatural and unreadable![1].

If that's your personal preference, that's fine but be aware that many see HTML custom attributes to express a pseudo-language ("ng-for", "v-for", etc) is not really HTML. Yes, it's cosmetic HTML for appearances sake but not semantic HTML. The semantics is the pseudo-programming-language that's executed by Javascript. If you're unaware, the extending HTML with custom attributes for expressing code is an example of The Inner Platform Effect.[2] It doesn't matter whether you use new HTML custom tags[3] or custom attributes; that's just a difference in cosmetics.

[1] Examples:

https://news.ycombinator.com/item?id=10967000

https://news.ycombinator.com/item?id=10967789

[2] https://en.wikipedia.org/wiki/Inner-platform_effect

[3] tag soup to express a pseudo-programming language in HTML: https://blog.codinghorror.com/web-development-as-tag-soup/

> (this is HUGE. I could write a whole blog post on this).

and please do

>And why the hell you have to write code in JS that will be ultimately represented as HTML?

If an analogy helps, the React virtual-DOM is philosophically similar to the very old and industry-accepted technique of double-buffering[1].

Your question would be similar to asking, "why the hell do you write pixel data to an invisible memory buffer if you're going to ultimately display it on the screen?"

The plain old HTML specification invented by Tim Berners-Lee and the traditional HTML rendering engines do not have the concept of an invisible "compositing layer" with a formal API standardized across Chrome/Firefox/IE/etc exposed to programmers.

The vdom is the computer science abstraction to bolt on that "compositing layer" to HTML. The React loop then renders the invisible composite layer to the real DOM.

[1] https://en.wikipedia.org/wiki/Multiple_buffering#Double_buff...

> Your question would be similar to asking, "why the hell do you write pixel data to an invisible memory buffer if you're going to ultimately display it on the screen?"

That's not an argument. VueJS for example also supports the VDOM thing and it doesn't require you to write templates in JS code. My point is that React requires you to cook templates in the way that's is more convenient for the React (as with JSX React gets DOM/template model pre-validated, no mess with converting HTML code to the template model), not for the template makers.

>My point is that React requires you to cook templates in the way that's is more convenient for the React

And likewise, Vue.js requires one to "cook HTML" with extra Vue extended syntax such as "v-if", "v-else-if", "v-for", etc. to make it convenient for Vue.js. (See sibling comment from lilactown that went into more detail.)

Since you weren't questioning the validity of vdom but was actually wondering why one would write pseudo-HTML (aka JSX) if it's going to be ultimately rendered as HTML anyway, you can turn that around and ask, "And why the hell you have to write template v-xxx _code_ in HTML that will be ultimately executed as Javascript by the Javascript engine?"

> with extra Vue extended syntax

Syntax remains the same as it's still just HTML with a custom attributes.

I don't get this obsession with "just HTML". Is it just for its own sake? What tangible benefits do you get when it's laid out that way?

I am fairly certain the reason is not readability because a lot of people get by JSX just fine.

> And why the hell you have to write code in JS that will be ultimately represented as HTML?

I only use React for React-Native, so my JSX gets turned into native objects.

Have you ever written a non-web program though? The default mode for almost all native GUI kits is for developers to define the UI in code.

I've never, ever seen a UI designer or a high level DSL (like HTML) that works better than code for non-trivial programs. With JSX, HTML has finally caught up to the rest of the GUI programming world.

> Have you ever written a non-web program though? The default mode for almost all native GUI kits is for developers to define the UI in code.

Surely I have. I do understand that with JSX you get the valid template model, not the raw HTML that will need to be validated and converted into the template model then. That's actually what I meant writing above message - it makes React's life easier.

> it makes React's life easier.

It makes the programmers life easier by allowing JavaScript, not just React, to reason about GUI components before they are rendered.

You can use JSX with something other than React if you want to. React just happens to be the most popular kit that is using it right now.

Huh? If you want React to render a div somewhere you presumably have to say the word "div" to it at some point. Would you be happier just saying React.createElement('div')? Because saying <div> in the middle of your javascript code is simply syntactic sugar for createElement.
It never gets turned into HTML. It gets turned into JS, which, eventually causes calls to `createElement(...)` etc. to happen.

You are writing declarative code that says what the UI should do. It is NOT - and I cannot stress this enough - a "template langauge" in the same way as Handlebars or PHP. There is no string interpolation anywhere.

> It never gets turned into HTML

Really? So users get the JS code in the browser rendered in the same way as the code source looks, not the dynamically built DOM model which has the native representation form of HTML? Surely JSX is an abstraction layer on top of the createElement thing, and that thing is a part of the building strict template model scenario.