5 ms·
As someone who does remember why because they've been building sites since the 90s, it's because the React team created a preprocessor (JSX) to let you embed HT
by wayfinder 3y ago
As someone who does remember why because they've been building sites since the 90s, it's because the React team created a preprocessor (JSX) to let you embed HTML tags in JavaScript. This fixed the problem that other languages like Java, Python, etc. don't have because those languages has assemblies/packages so they can put HTML templates in separate files and load them in your app. There is zero standard way to do that in JS and every custom way you invent looks like trash.
Doing something like this.shadow.innerHTML = `your HTML` with web components is terrible. document.createElement() is terrible. $('div').appendChild() is terrible. <script language="html" name="my-template"><!-- --></script> is terrible. HTML(Div(Strong(text))) is terrible*. Storing templates as JSON and writing a one-off loader is terrible. <div style="display:none">template</div> is terrible. I've done it every possible way and they are all terrible.
JSX fixed all that.
The biggest previous attempt at something like JSX was E4X where you could embed XML straight into JS, which was kinda nice except it added the entirety of XML and its complexity. I creamed when it came out but then I tried it and it was not it. (E4X ended up surviving a little longer in Adobe Flash though.)
E4X: https://en.wikipedia.org/wiki/ECMAScript_for_XML https://en.wikipedia.org/wiki/ECMAScript_for_XML
*This is what JSX compiles to behind the scenes.
- breadwinner 3y agoWhat if you could have the best of both worlds? What if you could use JSX templates and use standards-based web components? You can. Here's an example of using a web component in a JSX template (look for zx-listeditor): https://github.com/wisercoder/uibuilder/blob/master/WebComponentsDemo/Views/DemoPage.tsx https://github.com/wisercoder/uibuilder/blob/master/WebCompo... Here's how the web component is implemented, also using JSX: https://github.com/wisercoder/uibuilder/blob/master/WebComponentsDemo/elements/ZxListEditor.tsx https://github.com/wisercoder/uibuilder/blob/master/WebCompo...
- wayfinder 3y agoNot saying that you can't. I'm just explaining why React won and how it was blatantly obvious that it was going to win when it came out (that is, if you were there in the before-times).
- breadwinner 3y agoAgree with you on that. React was a breath of fresh air compared to what we had in the before-times, such as Angular, Ember and so on. The canonical demo of Ember.js was two-way data binding. React did away with two-way data binding and introduced JSX syntax. This was a major step forward. Code suddenly looked sane and readable. Then they took two steps backward when they introduced hooks. Code went back to being unreadable.
- chatmasta 3y agoAlso, the entire OP article is demonstrating this... I'm not sure many of the comments here actually read it...
- zelphirkalt 3y agoInteresting. Yet I find that React HTML—that is not actually HTML, but a look-alike, a dialect if you want—to be exactly what I dislike about React. That is because it still encourages people to put JS in their HTML in their JS in their ... And we are almost back to crazy PHP land of "I treat HTML as a string and blend everything together into one big lump.", instead of using a templating engine, that treats HTML in separate files, or making use of a DSL, that treats HTML as structured data, say for example SXML. Also there are issues with that custom HTML-look-alike preprocessor, because you cannot write class="...", because then somehow it gets syntactically confused, because "class" is now a keyword in JS. This all feels rather half-baked. Why can't the parser/prprocessor distinguish between that "class" and "class" in JS source code? We can have reusable HTML snippets (some may call components) with normal templating engines easily. Look at something like Jinja2 and how to reuse blocks and macros. Yes, some React component can encapsulate its own interactive behavior. That is only because we are already writing JS though, so we can already write frontend logic. But do we actually want that? Coupling state and behavior? I think we might not. Writing a script that gets served only on those rendered templates, where it is needed is not so hard either, when using a normal templating engine.
- wayfinder 3y agoYour criticism was the biggest one of React when it came out -- mixing view code with your controller code. Big no no. Everyone loved the MVC pattern (model-viewer-controller where you separate these things in different places) and what React did was a big no no. But you know, if you are trying to put HTML templates in separate files, you have to now send extra HTTP requests. That's an even bigger no no. In other languages, you can just put your template in a separate file and load it from your package/.jar/assembly. Super easy and most importantly, 100% standard and provided by the environment. So people just settled with React because it worked and no successfully invented a standard bundle format for the web. F' it we said.
- nostrademons 3y ago> But you know, if you are trying to put HTML templates in separate files, you have to now send extra HTTP requests. That's an even bigger no no. It's not actually, with HTTP/2. The separate requests are all multiplexed over the same connection, often with prefetching, and compressed together so that there's little to no overhead vs. putting them in the same file. This illustrates a common failure point for web frameworks though. They encode a lot of folk knowledge about how the web works, but that folk knowledge becomes obsolete as browsers change. Another prominent React example fits into this category: the virtual DOM. React assumed that DOM manipulations were slow and Javascript manipulations were fast, and so they built up an internal representation of the DOM in Javascript so they could manipulate that one and diff the change to apply it to the real DOM. This was true from approximately 2008 (when V8 introduced JS JITting) to 2013 (when Blink/Webkit/Firefox all moved to a dirty-bit system for DOM manipulations), which not coincidentally is when React was designed. But since then, DOM manipulation has been just pointer swaps and a dirty bit flip, and if you're careful not to invoke any operation that triggers a reflow and repaint you can make your modifications directly in the DOM for roughly the same cost as making them in JS. Since React is declarative it could easily have enforced the no-reflow rules without the virtual DOM, but because DOM manipulations were expensive when its designers learned web programming, it introduces an unnecessary concept.
- nostrademons 3y agoI liked the templates-as-JSON approach much more than JSX. HTML is terribly verbose, doesn't fit well with the rest of Javascript, doesn't let you use JS language features like destructuring or iteration on the component tree, and doesn't let you factor out common properties into their own data structure. Would much rather see: { tag: 'div', padding: '2px', position: 'absolute', content: [myText] } than <div style="padding: 2px; position: 'absolute'">${myText}</div> The main reason I ended up settling for JSX was just convention: I don't want to be the one with my own unique format for UI trees unless I can convince everybody else to use my format. Note that Jetpack Compose has a very similar declarative reactive paradigm as React, but represents components with Kotlin language mechanisms. IMHO I like it much better, because it's much more composeable.
- marcosdumay 3y ago> <div style="display:none">template</div> It's new and has no significance for the history. But I think it's relevant to point out that <template id="myhtml"><div></div></template> isn't horrible. And that those articles about web components are doing a really bad job of using constant strings instead of this.shaddow.innerHTML = getElementById("myhtml").innerHTML.
- wayfinder 3y agoThe implementation is new but as far as the UX goes, it's very similar to <script language="html" name="my-template"><!-- --></script>. That said, the UX is going to be slightly better for <template> simply because it's is an official standard and so IDEs and tooling will be more likely to support it without additional extensions or plugins.
- marcosdumay 3y agoIt's much more descriptive and obvious, and it's just plain HTML, so anything that assists you on writing HTML will assist you inside the templates. It's bad because it's inline and your templates have no obvious place to go. You also can't import them on the fly (or rather, it's as idiomatic to import as any HTML). And obviously, because they have no effect on HTML and can only be used in javascript
- vitaflo 3y ago100% agree. Like you I’ve been building sites since the mid 90s and always was pulling my hair out at all the convoluted ways we would attempt to handle HTML in these JS frameworks. As someone who knows HTML and CSS and vanilla JS, as soon as I saw React all I could think of when I saw JSX was “finally!”. Yeah it’s another framework with its own quirks but it lets me think about the UI in the same way I’ve thought about it for 25 years. For someone like me that’s a godsend.
- gitaarik 3y agoThen you would love Lit [0]. It is like JSX, but then using more native html template technologies. [0]: https://lit.dev/ https://lit.dev/
- xtracto 3y agoI remember using PHP and CodeIgniter in the mid-2000s. IIRC PHP had that template-interpolation thing solved since the first day: You populated your Views with PHP code.
- WorldMaker 3y ago> HTML(Div(Strong(text))) is terrible* > This is what JSX compiles to behind the scenes. Oh, it is much worse than that. By classic default it is: React.createElement('div', { /* props and attributes ... */ }, React.createElement('strong', { /* ... */ }, text)) Recent updates and other JSX frameworks simplified the name of `React.createElement` to just `jsx` or `h`. I've seen projects that manually write `h` calls like that everywhere, and it is indeed terrible. (Source: I've just completed a bunch of crazy TSX work and got pretty familiar with the compiled forms.)
- wayfinder 3y agoYeah, you're right. I was kind of simplifying it. API-wise, it's more like document.createElement() but I didn't want to asterisk that because document.createElement() is actually a thing and I didn't want people to think it was a simple layer on top of document.createElement.