Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

What's with the hate for JSX? I think handling HTML as data makes much more sense and is much more convenient than dealing with dumb templates or weird DSLs like Vue's or Angular's.


JSX is closer to JS than HTML, which means it annoying to write in some cases. Quick, what does this render as?

  <a href="...">Link 1</a> |
  <a href="...">Link 2</a> | 
  <a href="...">Link 3</a>
It's not

  Link 1 | Link 2 | Link 3
as you'd expect - instead, the whitespace after the pipe character is eaten by JSX. This is because HTML is whitespace sensitive, but JS is not, and so to allow indentation, JSX trims whitespace.

Here's another -

  <dl>
    { Object.entries(definitions).map(([term, definition]) => (
       <dt>{ term }</dt>
       <dd>{ definition }</dd>
    )}
  </dl>
This does not work - instead, you need to return an array, but the result is ugly - the commas are part of JS, not HTML, and don't appear in the output, but reading this quickly it's hard to see that (the difference is the braces surrounding the block).

  <dl>
    { Object.entries(definitions).map(([term, definition]) => ([
       <dt>{ term }</dt>,
       <dd>{ definition }</dd>,
    ])}
  </dl>
Vue's 'weird DSL' is HTML (the same is not quite true for Angular's). What you see is exactly what you get. Having a DSL also means you can define your own syntax. Things that are verbose (due to historical reasons in JS), such as iterating over an object, can be made simple -

  <dl>
    <template v-for="(definition, term) in definitions">
      <dt>{{ term }}</dt>
      <dd>{{ definition }}</dd>
    </template>
  </dl>


I disagree on your first example: I've historically found the extra whitespace a huge PITA for years. It causes extra "unpredictable" spacing in your design which is usually unwanted. It's only an issue for multi-line prose. React is opinionated here but I've found it's the most useful option.

On the 2nd point, you are partially correct. In general it's a code smell - strongly consider making it a component (in part for optimization). But definition lists are specifically strange: Unlike other repeating elements in HTML they don't have a container element like tr, li, fieldset, etc.


It's funny you bash JSX, which is a very thin XML-like DSL on top of JS, and then turn around and claim that Vue's DSL is HTML

   <button v-bind:disabled="isButtonDisabled">Button</button>
   <div v-bind:id="'list-' + id"></div>
   <form v-on:submit.prevent="onSubmit"></form>
   <a @click="doSomething"></a>
Something tells me JSX is the better DSL.


When you make it so that (which is how everyone is writing Vue anyway)

   <button :disabled="isButtonDisabled">Button</button>
   <div :id="'list-' + id"></div>
   <form @submit.prevent="onSubmit"></form>
   <a @click="doSomething"></a>
It gets really, really clear that anything not in {{ }}, or attribute not prefixed by @ or : is HTML.


What's the difference between :disabled and the regular HTML disabled? Same for ID, etc. How do strings differ from variable names?

The only way I see that as being more "intuitive" is if you're familiar with other templating languages.

JSX is far clearer:

  <button disabled={isButtonDisabled}>Button</button>
  <form onSubmit={handleSubmit}></form>
  <a onClick={doSomething}></a>
All you really need to know is everything between braces is plain JavaScript, and property names are camelCased.


...and property names are Javascript property names. Because, well, JSX is a very thin layer on top of Javascript


Good point about the whitespace, but I'd still rather have the templates inside my code than separate the two, mentally parsing two separate languages with different syntax and stitching them together is a lot more mental overhead IMO.


It's a matter of personal opinion, but I guess I'm more used to server-side templating languages, which Vue's looks much more similar to. I have the same problem as you for JSX - I keep trying to read it as HTML, except it's not, and mentally translating it is annoying.


i assure you, you will get over that phase real quickly. you will come to appreciate how nicer it is to write your code this way. because the same thing happened to me.


Your not mentally parsing two languages. Your parsing business logic in js and templating in regular html.

You still have to understand html inside weird jsx code...


If you want whitespace, the proper thing to do is to use &nbsp; HTML entity.


  {' '}
Not the prettiest, but doesn't come up often in my experience.


No, that has other implications.


Surely the huge win for JSX is that you can type check it?

I have a Typescript + Angular 1 project. The app logic feels robust as Typescript makes sure I'm using the right identifiers, variables aren't null/undefined etc. The Angular templates are a constant source of annoyance: they aren't type checked and aren't part of automatic variable renaming refactorings.


This is ultimately what makes React the right choice for me. A big part of the whole code=data thing is that code can be typed, which means now your data (markup) can be typed as well.

Of course this only really matters if you use Typescript/Flow.


Wow that is a good point! I have the same experience with Angular.js 1 and TypeScript.

Can someone confirm that you cannot type check Vue.js templates (without using Vue.js JSX support of course)?


I'm not a Vue user but I can't see how they would be type checkable without using JSX.

For the Angular 1 project, I'm thinking as a stepping stone we could introduce JSX templates before migrating to Vue or React later.


Especially that Vue support JSX and can be used without templates.




Consider applying for YC's Fall 2026 batch! Applications are open till July 27.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: