I'm someone that initially hated the look of JSX (the html markup inside of Javascript thing).
But I've learned to like it. React encourages you to keep components very granular and small and so the amount of markup in each component doesn't really get in the way I find. I've also learned to appreciate how easy it is to reason about what React is going to spit out onto the page because the view is right next to the logic that dictates the various states of the view. Feels very concise.
I still don't like the idea of it, but in practice it works quite well.
..I feel the same way. I prefer creating dom with code syntax.
You can replace JSX by hand-coding with React classes - take a look at the compiled jsx and mimic that. I find it as easy to work with, and less cognitive dissonance [ a personal preference ]
I actually am looking seriously at Mithril in preference to React for my next chunk of work.
I might swing the other way if React native became stellar [ and viably crossplatform ]
> Never understood why people liked React so much. I don't know why, but mixing javascript and HTML just looks... gross.
But you never write HTML with JSX, that's the point. XML like syntax is just sugar that gets transformed into functions. This is not HTML. With angular you need to use string templates which cannot be easily validated by IDEs for instance. JSX syntax validation is straight forward because it's directly integrated in the language.
Your end product has both HTML and JS so there's no way around mixing them somehow at some point. You could do it by keeping them separate and linking between them by means of CSS classes and magic strings in HTML templates. Or you can generate the HTML using JS functions. JSX just gives that latter option a pretty syntax.
If you don't like mixing logic into HTML you're free to create dumb components that only contain as much logic as you would want to put in a template. Such a component would accept properties and output a representation of the resulting HTML. A smarter component that does not generate HTML will provide the logic required for the template to function. That approach actually encouraged and is the right way to do React.
The bonus of this whole generate-HTML-representation-with-functions thing is that you pass around native JS values instead of stringified values and magic strings. Want to provide an onClick callback? Pass a callback. Not some magic string that represents a key which holds the callback in some object defined by framework-specific convention. No, you just pass a raw javascript function that will be run on click.
This might seem like a trivial distinction, but it's the difference between writing native JS vs writing magic framework code. I vastly prefer the former.
Thats the paradox you either go one way or the other. The problem with Javascript or something that turns into Javascript in HTML is it can inevitably lead to magic variables. I don't know how many times I have went in to support another developers angular code and found a variable who's origin can be traced to a scope variable which has been declared and initialized in an HTML file and all the sudden is magically being used halfway thru a routine. It's just shy of globals.
At the end of the day you go one way or the other, my preference is the template not having the ability to affect logic as it is not natural to look thru templates to find what is mutating the state of your application. I liked Dojo and I think react is a step back in that direction which in my personal opinion is the right direction for large web application.
React providing a mustache-like format (like ractive.js uses) would be great - more familiar than JSX and less clumsy than createElement().
Edit response to person below (rate limit): there's no 'problem', just that mustache is still more familiar. Moving JSX into a different file doesn't change that.
JSX/createElement is not just syntax sugar though. It avoids the whole step of parsing the template. Because JSX is JS code, you can pass native JS values to it including callbacks. Whereas anything you could pass to mustache-style templates will be stringified.
So for example in case of parsed templates, to pass a callback to onClick you'd need to define a convention on how you're going to locate the callback by a given string (since you can't pass the function itself, you need to pass some "name" of that function). Whatever logic that will be, the result will not feel like React anymore because you're back to typical framework-specific template magic instead of using plain JS.
This is not what I'm doing. JSX is JS. I'm not putting any logic "in HTML". If I were able to express what I'm doing in mustache-style syntax, it would be:
So, once again, JSX is JS. You're free to write the exact same thing without XML syntax. If you don't like that either, then what you're really saying is "Don't generate HTML using JS". Why not? The benefits are obvious:
* With React & ESLint you get basic checks to make sure you're not passing non-existent variables
* Your IDE understands what you're doing and lets you jump to callback definitions
* You understand what you're doing because you have one obvious place where you do templating and data binding.
* Your actual behaviour logic is still separated from your template, living in some other JS file.
On the other hand, if you add event listeners to HTML from JS the classic way, you get other problems:
* You're querying the DOM tree by CSS classes or some custom attributes. It's surely a familiar way of doing things, but also fragile and unintuitive.
* It requires your JS to know the structure of your DOM to some extent, and that structure is defined elsewhere. So it's basically the same problem as with mustache templates – passing around magic strings – but the other way around.
Mixing of logic and presentation is bad for application, but so don't use <font> tag in your code, because it will be hard for _designer_ to change appearance of hardcoded page.
React mixes logic and structure, which causes no harm, because both are written and maintained by same developer.