Hacker News new | past | comments | ask | show | jobs | submit login
JSX is no longer my friend (medium.com/jador)
200 points by tosh on March 15, 2016 | hide | past | favorite | 137 comments



This needs to be prefaced: this argument is overdone. JSX is not hard to learn. It's an order of magnitude better than the hampered DSLs of handlebars or dust, and I'm concerned that any engineer is so scarred that learning it takes more than 5-10 minutes of RTFM. After all, TFM on JSX is all of 200 words or less [1].

I've been using JSX since React 0.4. React's greatest strength is its simplicity. You can read all of React's documentation in 20 minutes. There's hardly any learning curve compared to the larger JS frameworks out there. It's all just JS*--no "logic-less-ish-kinda-sorta" template for loops, or two way data bindings, or figuring out when to render.

I don't think JSX is the terrible problem the hyperscript people make it out to be, but I think it might be time for it to retire. While JSX is as mild as learning curves come, it's still a learning curve. It still requires transpilation. It requires the extra characters. To reframe the conversation, does it make sense for the learning curve to be "it's HTML-ish with caveats like camelcasing but it works like JS" or "it's a collection of functions that generate HTML that are named for the HTML tag they generate."

I'm also really interested in the "but it makes sense to designers" argument. Is that actually true? Are there designers out there who understand JSX but wouldn't understand well formatted hyperscript? I feel like that's saying "yah I get ERB but HAML doesn't make any sense."

Again, I don't think this is a big enough deal for the amount of attention it gets paid. I'd love to see the React team bring in first class hyperscript-like syntax that is 100% JS, but it's hardly a reason to not use React.

[1] https://facebook.github.io/react/docs/jsx-in-depth.html


I don't understand the OP's argument either.

I'm primarily a back-end dev with a bit of HTML+JS xp, and I had zero issues with JSX when I decided to use React for a small project. I didn't find JSX confusing at all, it took me about 10 mins to understand the syntax fully and the error handling was very explicit. I'm not experienced at JS frameworks (have used Knockout and that's about it) and I'm certainly not from a front-end or designer background, much the opposite actually.

What really bothered me at the time was that my code was messy and I was struggling to properly wire up the React components with my data model - thankfully I since discovered Flux and then Redux :)


I've also been using JSX since the good old days, when a component was just a function -- "hyperscript" (such as it is) was built right in. Notably, writing React apps in CoffeeScript was beautiful:

    div
      className: "greeting"
      "Hello, world!"
As you pointed out, the biggest problem with JSX is not that it isn't JS, it's that it isn't HTML. It's a leaky abstraction. Camel casing is only the most obvious problem, things like className and htmlFor are more insidious.

So as soon as a developer realizes that it's just sugar over JS, they are in a world of trouble, invariably trying to stick an if-else into it. If everyone had enough grounding in language theory to tell them: "JSX is just a JS primary" all would be well, but alas, that's putting the cart before the horse.


JSX always felt hacky - the cleanest thing I've seen in this area is ClojureScript and Reagent. And that goes for the whole React stack - it just feels like it was made in a wrong language - even the surrounding stuff like Redux.

Every single concept they hacked on to JS (immutable types, atom, declarative DSL, etc.) is a first class concept in CLJS - and it works beautifully even when building on top of their JS implementation - I feel sad they didn't just go "all in" on something like CLJS - they have more than enough resources to fix any implementation issues (ie. they have the resources to create a compiler that would generate code you would hand write with immutable.js and JSX - after all they are funding stuff like Flux and babel).

I understand why they didn't do it but it still feels so bad to see a hack in a place where a beautiful solution was just a step away.


Or even more beautiful - purescript-thermite. But just as js people are scared of Clojure, Clojure people are scared of Haskell :)

(it's a joke)


I've been a Clojure dev full time for a few years, and last year I looked into Haskell quite a bit [1]. But ultimately the fact that Clojure can do live-programming is what really kept me preferring Clojure. And I'm not even talking about that figwheel stuff. I mean just being able to mess around inside the JVM live from an Emacs buffer via Cider, and reloading parts of my code while my app is still running during development. I'm not interested in giving that up, it's made me more productive than I thought I could ever be.

[1]: http://sdegutis.github.io/


Live coding with ClojureScript/Reagent/Re-frame/Figwheel/REPL is a holy-grail-kind of dev experience for me (and React really does feel like it was ported to JS from a better place), but one has to admit the potential maintainability/refactorability issues when projects grow beyond a certain size (as compared to something like Haskell or PureScript).

Plumatic Schema [1] goes a long way towards narrowing that gap though and I cannot recommend it enough. Whether it goes far enough in terms of safety is certainly a matter of project type/size and personal preference, but to me, for my kind of work so far it does and they'll take away my ClojureScript when they pry it from my cold, dead hands. :)

Also (and slightly off-topic) the combination of clairvoyant + re-frame-tracer [2][3] (+[4] for some minor, so far mostly React Native-relevant additions) should be way more popular than it seems to be. It's definitely one of the most important tools in my toolbox and completely changed the way I approach debugging.

[1]: https://github.com/plumatic/schema [2]: https://clojars.org/day8/re-frame-tracer [3]: https://clojars.org/gnl/re-frame-tracer [4]: https://clojars.org/gnl/clairvoyant


You can do that in Haskell as well though [0]. With ghci, making a code change is almost instantaneous even for big code bases, and you are assured that your code is self consistent. Then mess with your long-running state all you want.

At least for backend stuff, this is no worse than Clojure.

Give it a try :) Ping me if you have any questions.

[0] http://chrisdone.com/posts/ghci-reload


This is one part of the CLJS story that I think prevented it from becoming more widespread - it lacked a good REPL/compile story for a long time because of closure compiler. I would almost characterize that decision as a premature optimization - they focused on producing small output from the start, IMO larger JS size wouldn't matter that much in majority of use cases (you won't use CLJS to write websites, and webapps can tolerate few hundred k or even a MB of JS that's easy to cache), but they gave up one of the signature strong points for CLJ/Lisp so it wasn't as attractive even to CLJ devs.


I'd like to learn enough to understand the statement "JSX is just a JS primary," and I can't find out what a "$lang primary" is in PLT. Can you point out some resources for me to figure this out?


The full name is primary expression. The meat of it is that a primary is usually just a literal value, identifier, or something in parentheses, but it varies based on the particular language.

For a deep dive you'll want to read resources about parsing. To name one article that came up recently on HN, take a look at "Why Parsing Tools are Hard" [0].

[0]: http://blog.reverberate.org/2013/09/ll-and-lr-in-context-why...


The previous comment is trying to sound smart by using obscure terminology. I would guess they mean to say that JSX is a translated subset of JS?


Thanks for your generosity. This is what I was referring to: JSX extends the PrimaryExpression in the ECMAScript 6th Edition (ECMA-262) grammar.

Please take a look at the draft JSX spec [0] for details.

[0]: https://github.com/facebook/jsx


Replacing JSX with Coffeescript is really beautiful, and makes large components much more readable. I am a bit worried as it does not have much traction. JSX does not even allow to copy-paste from HTML as we need to rename all keys containing hyphens with some CamelCase.

Here is some of my Coffeescript render function, it is much more elegant than the equivalent JSX.

render: -> div className: "btn-group" role: "group" style: width: '100%'

        for option in @props.options
            label
                key: option.value
                className: @buttonClass @state.selected == option.value, option.bsColor
                style:
                    minWidth: (100 / @props.options.length) + '%'
                input
                    type: 'radio'
                    required: true
                    name: @props.name
                    value: option.value
                    checked: @state.selected == option.value
                    readOnly: false
                    onClick: @handleClick
                    "data-key": option.value
                    option.label


It doesn't have as much traction because as a whole, coffee script is almost always unreadably ambiguous (even moreso than jsx).

And the best parts are already here in es2015.


In what sense are you using the word "primary" in "JSX is just a JS primary"? I have a passing interest in language theory and strong interest in PL theory, but I don't think I've seen usage that before.


I specialised in programming languages in university, and I, too, have not heard of that term. :/ @OP: some exposition please?


The full name is primary expression, things like literal values, identifiers, and other expressions in parentheses.


Thanks!


I'll know the answer to your question in a couple weeks. I'm working with web content developers who are very good with HTML and CSS but less familiar with JavaScript. We have a project using Mithril (architecturally like React) where we started out without MSX (exactly like JSX) but they think they're going to prefer MSX syntax so we've begun switching over.


I've worked with designers with limited JS knowledge on a JSX-free react code. There may have been a short learning curve, but it didn't seem to slow them down much at all, even really early on, certainly not after a week (at that point our codebase was coffeescript, so JSX wasn't a great option).

It may have helped that we converted an existing code base (so there was a lot of html-as-JS example material to see), and devs were around the corner for any questions - but in my experience, JSX did not appear to be relevant, not at all.

The only advantage jsx does have IME is that it enables copy-pasting real html (sometimes with minor alterations) into your source, and that's a mundane but constant minor boon. All the examples on the net are in html; and if e.g. you use browser dev tools to rearrange a page to look like you want it you can easily copy-paste that back into the source. I don't think that advantage is worth putting up with JSX for, but it's not irrelevant either.


On copy-pasting: here's a handy tool that converts HTML to hyperscript http://html-to-hyperscript.paqmind.com/


That cuts both ways, though, since that easy “copy and paste” turns into “copy and paste and find everything which conflicts”. That's annoying and in some cases even a source of confusing bugs.


So I'm the guy who wrote the post in question.

As the view counter started to exceed my expectations I thought there would be a fair amount of negative feedback. I was surprised that there wasn't much. Turns out that it's all here on HN! :P

First off, I can't believe all of you actually read that. You have both my sympathy and thanks. Even more thanks for commenting on it.

I want to address a few of the points brought up in the comments.

1| Yes the title is click bait. The title is the initial hook to the reader (and often the only thing you'll see before deciding to check it out). So by definition it is click bait lol It is also true.

2| The post wasn't intended to say JSX is bad or that you should use hyperscript (although I do think you should try it). It is an account of my decision to investigate hyperscript and some reasons why I chose to stick with it.

Each team and project is different and I am not so assured of my opinion to say that you should use hyperscript. I've seen some who genuinely prefer React.createElement. I've seen react-jade also brought up today. If there is a view abstraction that you like better then you should use it.

3| Yeah, the argument I present for why I implemented hyperscript may seem rather thin. For my team, however, it was not.

4| Despite the fact that we often talk about React and JSX in the same sentence they are not synonymous (see the "use the one you like" argument above). JSX does take some setting up to use. And you'd be surprised how often I field questions about the JSX transformer even though it was deprecated nearly a year ago...

5| The RTFM argument. If you knew the developers on my team they could tell you that I tell them to RTFM several times a day. I think it is very important for them to consult the docs whenever they have a question instead of me. That being said, I'd rather them RTFM about immutable-js or functional combinators than view syntax.

If you've got more heat lay it on :)


I started reading with skepticism and you hadn't convinced me by the end that you were any more or less "correct" than my own approach. That being said, I never for a second thought you were wrong and needed correcting either. Your tone never implied to me that the you thought anything similar about the reader either. Your responses in the comments on Medium basically confirmed in my mind that you were just talking to the void about what has worked for you and your team.

1| Don't let anyone bother you about headlines that attract readers and healthy conversation. Despite the romantic notions we may harbor about writing, it is an attention game for most who do it. Good headlines are a part of that game.

Kudos on handling the unexpected attention well :).


I have to say, and I'm honestly sorry I haven't gotten around to it till now, that I genuinely appreciate your kind and rational words. ^.^


FWIW my comment also blew up more than I woulda expected. I wasn't really responding to your article even, more to Andre's flavor over the top anti-JSX attitude. It's like you said: each team is different and should use what works for them, and making overblown arguments doesn't help that.

If I can double down on the mistake though, I'd be concerned if someone who didn't feel like learning how JSX works tried to dive into immmutables and combinators :D.

Thanks for react-hyperscript-helpers! Feels like react-native in a good way.


To a certain extent I think Andre's arguments suffer from being 140 chars or less. Seems like he's yelling probably more than he is. And since he brings it up at least once a month I can understand if there is a bit of eyeroll.

Haha, fair enough. Something that I didn't mention but I suppose bears noting, I have, not so secretly, been moving the organization I work for towards elm. hyperscript is much more akin to elm-html than JSX is, and is one of the "comfort level" stepping stones in that effort (along with immutable data structures, combinators, pure functions, etc). While the things I mention in the article were my primary motivators, I'd be lying if I said the above wasn't a factor too.

Thanks!


The thing that the author misses is that JSX is very natural for designers. If you properly encapsulate any logic into methods on the component rather than having it all inline in the render return, even designers with mediocre technical skills can productively work with JSX files. This can be a huge productivity win, and beyond that honestly I don't know many engineers that enjoy translating designer mock-ups.


JSX is also very natural for people who've written HTML for years.

I wasn't a fan when I started, but now I love it to bits.


I fell in love at first sight. Since it was in wide use at Facebook I got my team to take a look at it. Now they love it. Once you start breaking up things into small mostly reusable components, the true power of JSX shines through. And since most files never end up being very large with well reasoned interfaces between components, it's much easier to reason about your user interfaces.


My brain parses JSX way better than Hyperscript, so I will stick with it and suffer the extra keystrokes.

And the context switch has not proved to be a problem for me, but I'm sympathetic to the argument.

</2cents>


I very much like how the recommended Hyperscript looks, but the package was last updated last December, and it doesn't even list React 0.14 in the compatibility list: it stops at v0.13, which was released in May 2015. Half a year before the last update of Hyperscript.

It's arguably a small package that you could just rewrite if things go wrong, but is it a smart idea to base any project on semi-abandoned code?


That's what I don't like about a lot of bleeding-edge web development. You end up depending on a half-dozen abandoned pet projects. Somebody had an itch, scratched it, got bored.

I swear half of the gulp eco-system is just that - half-abandoned, half-working little cute plugins that someone did because someone else's plugin, even though 99% identical, didn't do the one thing they wanted, so they wrote their own and then abandoned it, instead of maybe contributing to the other one. Sometimes, web development frameworks and libraries just feel like a giant software ghetto - a giant web of dependencies that someone combined into something with little thought given to long-term maintainability.

One of my team members refuses to incorporate a dependency that is by "some guy" and hasn't had any commit activity in the last month.


If a major framework hasn't had commits for a month that might indicate something. If it's just some random module that's small and has no major open issues, then that policy is unreasonable. Does your team regularly audit the commit streams of already-in-use dependencies so you can rip them out when the maintainers take a break?


It's more of a tongue-in-cheek thing but it was born out of real frustration. It really depends like you said - it helps to look at the source code and see if it is maintainable by our team in case it is abandoned.


It almost feels that way about a lot of projects, even the ones sponsored by companies from Google down to the small fish.


If you think you'll like it you should just try it. hyperscript is tiny and probably doesn't need any changes to support any conceivable React version. If bureaucratic checkboxes are important to you then do some testing and submit a PR. If there are issues related to React updates then they'll probably get fixed when they are reported.


This article includes a tweet which demonstrates a very contrived example of a for loop using JSX. If you're ever writing code like this, please reevaluate your career in software development.

As an aside, we recently moved from Nunjucks templates to React / JSX at work and the frontend team couldn't be more pleased. Components reflect improvements made to them across the board and provide a happy medium between designer and JS dev. I have also found a lot of power in refs by implementing superclass functions that provide reusable logic for elements based on the key of the ref when certain functions are implemented on the corresponding component. This can be used for state persistence in forms, analytics or anything else the developer imagines.

Context switching has not been an issue but all of our frontend devs also do work on the backend. This may be an issue to consider for teams that don't embrace cross disciplinary roles.


"If you're ever writing code like this, please reevaluate your career in software development."

That's a pretty nasty comment to make about anyone in this industry over a simple for loop.


I apologize and you are correct in stating this. Less experienced developers may come across these sorts of mistakes when conflating JSX with templating languages that contain logic constructs (Handlebars et al). It is important to clarify.

To be more constructive, I believe an understanding of when to use the right tool for the right job is paramount to a good software developer. JSX nodes are suitable for representing UI components but certainly not control statements such as a for loop.


Well, it is just plain wrong. Even if you wanted to do a for loop in JSX you'd do

    <div>
        {for (var x=0;x<10;x++) {
            <div/>
        }}
    <div>
Not a templated component like that. That said, I have created repeater components and the like before, largely because JSX is so friendly that more design-minded people can use it very easily.

EDIT: turns out that doesn't actually work, ha. I've never written JSX that way.

    <div>
        {[0,1,2,3].map((i) => {
            <div/>
        }}
    <div>
on the other hand...


You just proved the author's point. The JSX you provided is invalid, since you can't pass `for` as a function argument (see his equivalent bit about `if`).


Huh. Well, my only defense is that I would never even try to write JSX like that anyway - the actual JS in my JSX templates is basically just Array.map calls.


Generally speaking, I do not recommend this pattern. My preference is to handle enumeration within a function, for example:

  <ul>
    {this.listItems(items)}
  </ul>
Then, within a function implemented on the same component:

  listItems: function(items) {
      items.map((item) => {
          return <li>{item.name}</li>
      });
  }


Is it just me, or is the return missing in the `function` (or am _I_ missing something :)? Not important of course, just pointing it out...


Good catch! I wrote that example in a hurry on my lunch break so I take accountability for the mistake.


If you omit the {} you can then also omit the return.

https://developer.mozilla.org/en/docs/Web/JavaScript/Referen...


True but irrelevant, the GP is talking about the top level function, not the fat arrow one.


Guess I was also in a hurry!


That shouldn't work since syntactically you are in a middle of a function call where you can only have expressions. This is funny because one of the author's point was that JSX makes that confusing because you would never think to write `callFunction(for (var i = 0; ...))` normally.


Are you referring to .map()? Its a standard array method in every language with first-class functions. Why would you prefer a for loop?


Well, it's a negative example. So you and the tweet are saying the same thing


This person and the person he quotes seem to be quite confused about what JSX is and how it works. Hyperscript looks cool and use it if suits you but I don't think most of these reasons are valid nor actually make sense (like https://twitter.com/andrestaltz/status/674313202197520384?re... isn't related to JSX at all)


Better markup DSLs have already been written, which "mingle" better in code: HAML and Jade. Unfortunately reactjs-jade never gained any momentum it seems.

Hyperscript seems like a "reasonable alternative" to JSX. I won't say "better" because you're trading <angle brackets> for `h([ , ])` symbols that also contribute to line noise. And other common pain points like "you can't put an `if` block inside your markup" still persists.


I disagree. I have no desire to go back to jade


no offense to the author, seems like hyperscript has achieved what it hopes... but the benefits of not having to learn some confusing piece of JSX-ness do not seem to outweigh the cost of h('strong','uglify')-ing everything from a legibility standpoint.

disclaimer: only read the README, didn't try actually using hyperscript.


It would be nice if it had more of a Jade indentation like syntax. The angle brackets and closing tags are just syntactic noise.

If we want to go with the code route then the DOM as code is actually really clean with Coffeescript.

Elm is interesting but I don't like having to do [] (empty array) when there are no attributes or [] for the children when there are obviously no children (hr, br, img, etc).


It is an alpha-quality library, but I've been playing around with something like this, using ES2015 template strings: https://github.com/af/slashpile

I've yet to figure out if the run-time performance hit is reasonable, but I vastly prefer the syntax to either JSX or hyperscript (I previously wrote a hyperscript-like library as well, and have used it for several months)


Notably we must first understand that there is a differemce between react as a framework and jsx. Jsx provides a means to generate ui patches which in turn resolve to html through react. What makes jsx so great is that it looks like html so you dont have to think in some special library way. Your using pre-existing technologies which is wonderful.

A more important point is the handlebars. So, handlebars implys block in javascript but what is actually happening is the context is evaluated and passed to the component. Kindof how parenthesis work

(A || b).property(array.sort(compareFactory())

The fact we use handlebars when the text inside is actually evaulated how parenthisis work probably enables this sort of confusion. The reality is handlebars is for the angular/mustache crowd and to ensure they feel at home. But in parenthisis would build on exisisting knowledge of how js works

<div count={count?true:false} />

<div count=(count?true:false) />


The "handlebars" are just plain javascript syntax for a block, not template markers. You can try it in your browser console.

    { console.log(123); }


Not exactly... within JSX the handlebars signify "now I'm going back to plain JS".

compare

    <div>
        console.log(123)
    </div>
with

    <div>
        { console.log(123) }
    </div>
The first outputs a div with the text "console.log(123)" inside. The second logs "123" and outputs an empty div (since console.log returns undefined).


That's the point.


Not exactly. The stuff within the handlebars isn't evaluated, it's just passed through as code rather than a string. Your example is equivalent to this:

    React.createElement(div, { count: count?true:false })
not, as your comment implies,

    React.createElement(div, { count: true })


Honestly, if I thought JSX was too complicated (it lints very well with ESlint, so even if it was problematic, you can just let the tool figure it out for you), all I'd do is use destructuring with the React.DOM built in element factories and call it a day. They're fairly simple to use, and then it really is just javascript.

But I've never seen anyone, not even the most junior, backend-only developer touching React for the first time, have any issues with it for more than 4-5 minutes. ESLint catches any mistake they make.

The only real argument, and it is a valid one, is that Babel does not use shorthands in the output, so it's a trainwreck to read. If that was the primary argument, I could get it. Though then IMO the solution would just be a better Babel plugin for development.


<For i={1} condition={i < 10} step={i++}>

Why would you ever do that instead of having the logic in the component itself?


A long time ago I tossed together a template-language DSL of my own[1] when a bunch of my friends complained that there were "too many choices" and that "we should just use plain JS and HTML without a complicated framework" (I feel like this tagline gets used by many newer 'microframeworks').

Sometimes you just don't want to RTFM, and so you get to enjoy the standards problem[2] rather than learning someone else's tool. Sometimes you just have a lot of spare time and want to re-implement something as a learning experience. But it's a good idea to acknowledge the technical merits of those who've come before when you want to go down that route - JSX is a _well done_ project. If you don't learn from it's good parts (familiarity, ease of use, prolific tooling), as well as the bad you feel you see, you don't get anywhere. The author became familiar with JSX to the point where his perspective of its benefits and flaws shifted - after using it for a long time you can forget its benefits until you no longer have them.

For example, I would argue that the contextual switching the author complains about is a _good_ thing - I find the extra hesitation helps you create boundaries and keep unneeded code out of your views.

[1]http://ham.io/not.js/ [2]https://xkcd.com/927/


Perhaps not the best avenue for this, but I thought I'd take advantage of eyes on this discussion. How might I go about using JSX outside of React or creating something similar? I basically want to turn custom <xml-style> code into JavaScript that instantiates custom classes that have nothing to do with the DOM. I'd like to do this via a babel plugin as well.

If you can't tell, I enjoy JSX tremendously and I'd like to use it or borrow from it extensively outside of React.


It's pretty straight forward to use JSX outside of React. If you're using Babel you can simply add

    /** @jsx ExampleDOM */
As the first line in your Javascript source file. This indicates to the transpiler to convert statements of the form

    <example name="Wesley" age={15}>
        <Message text="hello"/>
        <Message text="world"/>
    </example>

into

    ExampleDOM('example', { name: 'Wesley', age: 15 },
        ExampleDOM(Message, { text: 'hello'}),
        ExampleDOM(Message, { text: 'world })
    )
where you implement ExampleDom as

    function ExampleDOM(element_or_component, attributes, ...children) {


    }
Note that because 'example' starts with a lowercase character, it is transpiled into a string first-argument to the ExampleDOM function. If it starts with an Uppercase letter (i.e. 'Message' above) it is interpreted as an in-scope Javascript variable.

We've had really good results using JSX outside of the core react library. For example, we've built a "React.js for Excel" that lets us easily create rich Excel workbooks:

      <worksheet
        clear
        protect
        flow="column"
        name={`Bespoke - ${network.shortname} - WACC`}
        tabColor={theme.bespokeBlue}
        displayGridlines={false}
        style={worksheetStyle}>
        <PageLayout
          title={`${network.name} Cost-of-Capital Worksheet`}
          lastUpdated={new Date()}>
          <UpdatedWACCEstimates network={network} determination={determination}/>
          <WACCForecast network={network} forecast={forecast}/>
        </PageLayout>
      </worksheet>
Which looks a lot like React.js and behaves almost exactly the same, but it's targeting the Excel COM Object model rather than the HTML DOM.


Fantastic. Thank you for the detailed response and examples.



This article's direction makes sense for the task of 'writing HTML in JS'. I find that JSX true power comes when you actually start building reusable components for the many pieces of your UI.

This becomes even better when using a TypeScript capable editor with TSX, creating classes for the components and taking advantage of full autocomplete and syntax checking from your editor. Your code ends up pretty readable, composable and error free.


You can still get all of those advantages using React without JSX. Reusable components have nothing to do with JSX. Syntax checking/highlighting/etc. is arguably easier (in a global sense) without JSX since we don't need to fork acorn or esprima to get it.


I was nodding and agreeing right up until he got to the part where he was talking about how he's using Hyperscript as a replacement. Hyperscript's just the same problematic design with a different syntax.

Mixing HTML and server side code may let you do toy projects quickly, but in the real world it's a great recipe for building an unmaintainable, undifferentiated, monolithic mess.


The historical problem with mixing HTML and server-side code has been one of mixing responsibilities. I'd probably still recommend keeping them separate for an HTML/server-side code application, but for frontend work, it takes on a different character.

I work on very "functionality-oriented" applications; no dedicated designers here. Having a split between JS view code (example, in the form of Backbone views) and template code is just frustrating to deal with. React addresses the issue by putting the relevant pieces of view code together. The React code should be separate from other code types (whatever you would call it: models, business logic etc.), but that's just like what we are trying to solve with separating server-side + HTML.

I still think however, React is controversial. I would be considerate when deciding to use it, because I just don't think it is that important for many applications.


So how exactly do I specify the place where I'd like <date> if I can't do some variation of <span className="date">{date}</span>?


I don't have any issue with the hypersrcipt library presented here. In fact I find it interesting that, this is more or less how React used to work many versions ago. All JSX tags mapped directly to functions and there was no such thing as React.createElement. In fact I was always a little sad that React made that change, it was such a natural mapping. I understand there are under the hood implementation advantages to the move, but having the option to do React.dom.ul(...) was kinda cool.

That said I really don't find any of the authors arguments particularly persuasive. I work with many inexperienced JS devs and haven't seen them struggle with these issues in JSX. Not to discount the authors experiences, it just seems this article could have been more about highlighting the library, rather than creating highly contrived seeming examples of why JSX is bad. I also agree with some of the others, that the advantage of JSX mostly comes in working with designers and people more familiar with HTML than JS.


> React.dom.ul(...) was kinda cool

React.DOM.ul() works as it always did. Even if we change that (since it's kinda silly to ship down a big list of tags that we don't otherwise need), you can also do

var ul = React.createFactory('ul');

and then ul(). No big deal.


It's not that simple, and hyperscript [A] is much more practical than createFactory [B].

[B] requires the first argument always to be props, so most of the time for empty props, people end up always giving `{}` or `null` as the first arg. In [A] they are optional. In JSX if you don't have props you don't need to provide any "empty props" object.

In [A], children are always an array, while in [B] sometimes a single-child parent only accepts that child as last argument, instead of an array with one child. Otherwise it's a runtime error or warning. This special case treatment is only visible when using [B], but transparent when using JSX.

In [A], the first (optional) argument can be a CSS selector to declare the classnames and id. In [B] you have to give it explicitly as props.

All this indicates that while React supports a non-JSX workflow, [B] is way less practical than JSX, probably because Facebook itself uses JSX extensively, and supporting non-JSX workflow was an afterthought when releasing React to the public.


Since about December 2015 I have been learning React-native for my android needs. While I had programmed extensively in Javascript in 2008 (dojo) -- I have forgotten number of things, and just essentially re-learning (and I had never done a production mobile app before).

I find JSX, at least within context of react-native is very useful.

I specifically like being able to have this 'duality' of a view for a Component.

JSX allows a custom component to viewed by outside as first-class citizen of an HTML mark up. But within the component -- it is a class with members, Eiffel-like preconditions for construction, and explicitly managed state.

I think React-folks got the separation between Presenters and Interactors exactly right.

I would not mind even more features where the state management relies on channels that are can contain Parent, children, and may be even 'peer' events. (something like clojurescript's CoreAsynch for the above 3 categories of events affecting states for a given component).


In my opinion JSX is usable, and gets the job done. I have used it, and enjoyed it. However, my personal preference to write html is one that I think looks beautiful in comparison to template engines. Nicely enhanced by syntax highlighting, and perfectly pure in its structure. And with the most known syntax. It is the most simple and productive. It is: writing html in html itself. (I am describing my personal favorite, not saying that it should be the right way for everyone). I prefer frameworks that let me structure the html views of my projects, using declarative html.

In the same line, breaking things into components is best achieved, in my opinion, using web components. The syntax is a little muddy, due to all the html legacy cruft. But I find it better than the alternatives, for example react components. With web components, the great thing is that any styles and javascript functionality is scoped to the component. That allows for better separation of concerns in separated components. This is specially useful when you have components with functional styles: animations, transitions, etc.

After componetization is solved by web components, the problems with html in html boils down to mostly two things: generating multiple elements from some data, or setting data in elements based on some other data. For these things I prefer the syntax style of data binding and "repeaters". My favorite is polymer(https://www.polymer-project.org/1.0/). Example:

  <el-container id="listbox">
    <el-list-items itemsdata="{{model.itemlist}}"></el-list-items>
  </el-container>
And the concern of repeating multiple elements is trapped in a component. In the example above, in <el-list-items>. In general, when using this technique, data binding must not be abused, or the view becomes a mess.


have you tried vue? it has similar syntax but does not require polyfills.


I think the issue here is one of perspective. My thought would be that removing JSX and replacing it with other JS conventions may make it easier for new devs but I'm quite certain that now you've made your code base highly inaccessible for front end designers who just want to find the HTML hidden amongst all this code.


The decision to use JSX or not is really one of the least important decisions you need to make when writing a React application. It's essentially a style preference.

Personally I like JSX. It's nice having a special syntax that your editor and linter [1] can understand. And if you are part of the stateless/minimal-logic component camp then most of your components will look more like HTML/JSX with a little bit of JS interspersed than vice-versa.

[1] https://github.com/yannickcr/eslint-plugin-react#jsx-specifi...


After many Medium posts of uninformed, not very insightful complaints about react and the state of JavaScript I am becoming inclined to just avoid Medium posts about JavaScript in general.

Medium has become the analog to Tumblr posts for opinionated engineers to whine about things that don't really impact development in ways that matter.

Really all this developer had to do was talk about Hyperscript in a positive way and I would have found this post interesting instead of rolling my eyes paragraph after paragraph. Oh poor you and your angle brackets, such a burden! Putting HTML directly into my JavaScript is awesome and I never want to go back to separate template files ever again. It's wonderful and results in great code that works well, is readable, and is easy to test.


Seriously. If you like it, use it. If you don't like it, don't use it. If you work with a team, take a vote.

This post spends quite a bit talking about beginners who are learning Javascript, React, and JSX all at once. Of course they aren't going to get it right immediately, if they didn't get tripped up on JSX they'd get tripped up on something else. "Beginners don't get it" might be the weakest argument I've heard so far.


This is a dangerous opinion and one that weighs the present too heavily over the future.

Pick languages/frameworks that will produce easily maintainable code and will survive naturally after your departure from a company. New developers have a learning curve no matter what. The steeper you make that curve, the more danger you put your codebase in and the more likely you are to set them up to fail.


I agree, a better process than voting would be "evaluate the advantages and disadvantages of each practice and determine which results in the highest quality, most maintainable code."

But since when have we been any good at identifying future needs or identifying maintainable code? Just be consistent, try to at least leave SOME documentation for the next guy, and don't be actively malicious.


I think his points about new developers having to learn JS, React, and JSX all at the same time and then context switch between them in ways that aren't entirely clear was pretty spot on. I don't know how you draw that comparison without mentioning the shortcomings of JSX. Also with Hyperscript you're still building your markup directly in your Javascript, just using JS for it instead of JSX, not templates. Not sure if that's what you meant with your "separate template pages" statement.


But optimizing for those with no development experience isn't one of the goals of React. From the "thinking in react" page in the docs,

"React is, in my opinion, the premier way to build big, fast Web apps with JavaScript."

Nowhere in the documentation does it stress that it's easy to learn or ideal for beginners. If you don't know Javascript, writing React applications (or any application, really) is going to be painful. Full stop. JSX adds cognitive load when writing code, but reduces cognitive load when comparing the DOM to the component that created it. Given the amount of time I spent debugging and refactoring, I'm happy to use JSX.


Consistency is valuable for everyone, particularly when refactoring. You can't refactor JSX according to the rules of JS or the rules of HTML - you have to shift gears to refactor according to the rules of JSX (particularly hard since you're probably refactoring the surrounding JS at the same time). If it's possible to retain the code:dom correspondence with an approach that's based on (and follows the same rules as) vanilla JS - and it sounds like this Hyperscript does that - surely that's an improvement.


Whether or not React's goal is to cater to beginners doesn't make the argument any less valid. Also React doesn't equal JSX. The React docs also mention how to do things without JSX.

Maybe it's the article's title that has understandably rankled some people by seemingly maligning JSX. However, I think it's a very valid concern to have when ramping up a team that's unfamiliar with JS and React.


It doesn't make it less valid, but "is JSX bad" has been done to death. It's been the subject of Medium posts like OP since I started using it in 2014. If you're "ramping up a team that's unfamiliar with JS and React," maybe you should be deciding whether to hire somebody experienced with JS and React instead of deciding whether or not to use JSX.


Agreed, the title was link bait done to death.

I'm not in the situation of ramping up a team unfamiliar as the author was. But it sounds like he was experienced with JS and React himself. Or are you suggesting he should replace his team with people more familiar with JS+React?


The context switching argument is BS. That's just like complaining about 'context switching' when you have to use an hash/map/dict/object literal or a comment.


It's either this or "functional JavaScript" posts on my feed. Really, I've seen about ten "guides" about it in the past two weeks.


The author does seem to not consider the case of where you already have HTML and just plop it in and make it dynamic. Luckily JSX is completely optional, and a JSX->hyperscript converter being well possible means the syntactic choice remains only a slight annoyance at most.


> Putting HTML directly into my JavaScript is awesome and I never want to go back to separate template pages ever again.

Note that the author isn't suggesting a return to separate template pages. He is suggesting a system for creating React elements that uses simple functions and JavaScript syntax rather than the custom syntax of JSX.


This has been my view as well. Author comes off across as a 'tumblrina' and sort of obsessing over small annoyance rather than a serious writing on providing insight for real engineers who have better things to do than whine on medium


You could state your disagreement without casting aspersions on the masculinity and competence of the people you disagree with. Given that you yourself are wasting time reading posts on Medium and then whining about them on HN, I have to ask myself whether you are not a real engineer, or whether just maybe real engineers can whine about things sometimes.


If anyone was curious about other alternatives, we use r-dom at work. I am personally happy with it as an alternative to JSX.

https://www.npmjs.com/package/r-dom


JSX is the template layer not tied to React.

I think of it as a child of - XML + JS.

I am waiting for JSS - CSS + JS, for the styling part.

Radium [1] is a promising start.

[1] http://stack.formidable.com/radium/


I find tachyons css the best complement for react


this might be the wrong place to ask this, but i've been noting a few trends over the last 20 years or so...

why are web-developers so damned clever? do we really need to do all of this to ourselves?

the web is just a port, a protocol, and a model for interaction, underneath it all.

why on earth can we not live with the existing web, and move on towards inventing other spaces?

a browser is just a shitty sandboxed OS with a declarative markup renderer. there's nothing to stop anyone from making a different client-side x-terminal... (as that's what people are trying to turn the web into, apparently)



should we write {0x68, 0x65, 0x6c, 0x6c, 0x6f} instead of "hello"?

joke aside, I think JSX does a great job to reduce the cognitive load, bridging codes as representation and its result.


I'm wondering what the advantages of JSX are now in a world with ES6 template strings?

This seems plenty easy to read and write and has the benefit that it's pure JS and doesn't need to be compiled during development:

  const listItem = item => `<li><a href="${item.link}">${item.name}</a></li>`
  const listComponent = items => `<ul>${items.map(listItem).join("")}</ul>`


It was discussed a long time ago. Some googling found this very old link

http://facebook.github.io/jsx/#why-not-template-literals


Thanks for the link! This makes my case stronger as their example for why not to use literals is weak. Box should be a component that takes param(s), not a var for a tag name.


The compile is a huuuge plus. If you do a error in your template string (e.g. forget a '>'), you won't catch it until you run it in the browser. The JSX will complain loudly when compiled.

JSX >>>> ES6 template strings


Ah. I guess html errors yes. If you add "use strict" you will catch js errors at compile time. Plus editor should provide autocomplete in template strings. I wonder if anyone has provided a highlighting package for highlighting html inside template strings.


The difference is in when the code blows up if there's a typo. With JSX/hyperscript, it blows up with a syntax error at parse time; with strings, it blows up at runtime.


In my experience, if JSX becomes too complex to read/write, then that just means I need to break down my components.


And here it comes reinventing JSX under different name :)


JSX is little verbose but CJSX is a bliss.


I dont like JSX either. just a hype...


The author might like RiotJS instead.


And so the wheel turns...


JSX was never my friend. Compiling is so 20th century.


as much as people bash Angular, it was a relief just being able to take HTML code from a designer, sprinkle some ng- attributes and watch it come alive. I didn't even need to learn anything, it just made intuitive sense.

Unfortunately, as much as I want to learn React.js, there was too much context switching.

The only reason I'm persisting is because of react native. As soon as somebody comes up with a better way I'm ditching react

back to my good ol' jQuery


JSX strikes me as inelegant and I don't care for it, but I don't think I agree with some of these arguments here. If JSX is honestly giving you trouble or confusing you in some way you should take some time to practice, I think.


You really should edit your blog posts before releasing them. This is very clearly a one-take ramble and the quality suffers from it.


I don't like JSX also... Totally agree with the author... JSX is just a hype, as I feel...


Finally, somebody said it. I thought we abandoned that garbage when we left PHP, and now all of a sudden everybody wants to start mixing markup and code again?


Hyperscript is the same thing as JSX when used with React; just a different syntax. Either way you are "mixing markup and code."


There's no escaping the fact that when you have an array of objects, you're going to loop over them to generate html. At that points, it's idiotic to learn some contrived new templating language when you already have .map.

Seriously: Separation of Concerns is solved. Yes, you were once far ahead of the pack. But at some point _everybody got it_. It no longer needs a (cumbersome) technical solution because we solved it with education, and developers have been highly disciplines since almost the late 90ies.


So there's hope for using tables again as layouts in HTML?!


We abandoned mixing view logic with program logic. It's perfectly reasonable to use PHP as your template engine as long you don't mix your program logic into your templates.

React is a view engine; everything done in react is to construct and maintain the view.


The difference is JSX XML syntax is not a templating language but a functional one. In that sense it has nothing to do with PHP templates or any JS templating system based on string templating. it's XML directly in Javascript.


1) Like it or not PHP is still one of the top 5-10 languages used today.

2) The separation of concerns argument is completely invalid. They aren't separate concerns, they are separate languages.


Exactly this. Can someone explain to me what do people see in JSX way of creating components? What happened to good ol' code vs template separation and what's now wrong with having two separate files - .html (or jade, or whatever) and .js?


What does code/template separation actually achieve? Ignoring JSX for a moment, why are templates a good thing? Are you actually simplifying something by using {{#each}} instead of .map()? Is {{#if}} really better than if()? Seems to me like templates don't actually decouple code.


In a large application, it starts to become a pain to deal with. It doesn't obviate the need to be careful over mixing responsibilities. In general, React components should just be things that render out to the DOM. If the HTML code is in JS, it doesn't matter as much as the more important thing of separating out your application layers.


JSX always looked like an abomination to me. Don't know a single person who uses it


Know several teams using it personally, and am "internetically" aware of thousands upon thousands of programmers than use it. Maybe do a GitHub search?

It's nothing more than a DSL for a templating language that finally puts the template for a component where it belongs -- along with the presentation logic.


I assure you, plenty do. Including myself. I had a very negative reaction when I first read about it (much like the article author) after 5 minutes it started to make a lot of sense to me.


I know that many people use React and JSX. anecdotally, I don't know any of them personally




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

Search: