- JSX composes normal JavaScript expressions. That means that every operator/function/etc I have access to in JavaScript is also available within JSX. With Django templates, I need to create a custom tag or filter.
- JSX desugars to a normal JavaScript expressions. That means I can store it in a variable, return it from a function, etc.
- JSX returns a structured object, rather than a string. That means it can be used to support output formats other than text. This isn't so much of an advantage for web dev, where everything is a string, but it's a "least worst" situation if you use other targets like React Three Fiber, React Native, etc.
- The aforementioned type safety is nice!
On the other hand, I imagine Django templates are significantly more welcoming if you're more familiar with HTML than JavaScript.
By the way, the ternary in your JSX example can be removed by filtering the array:
<div>
<h1>Conditional Display and Looping in JSX</h1>
<ul>
{this.state.items
.filter(item => item.show)
.map(item => <li key={item.id}>{item.name}</li>)}
</ul>
</div>that doesn't make it more readable. its still a blob of typical unreadable functional garbage.
For things beyond if/for statements, the solution is usually to write custom tags in a DSL that I have a hard time grokking. With JS, you can write arbitrary logic in an imperative language.
We designed Django (back in ~2003) with the idea that it should be usable by frontend developers who just worked in HTML and CSS, which isn't really a category that exists much today any more.
We used {% %} for tags rather than XML-style partly because we wanted the tags to remain visible in Dreamweaver!
Yes, you give up the ability of designers and frontend-only people to easily work with the HTML templates. But in exchange you get quite a lot.
I'm not sure how to back that up... just look at it! Weirdest way I've ever seen to implement an if statement in a template.
A `for` loop doesn't really make sense from the JS expression viewpoint — `for` loops in JS are statements, and in languages that do treat them as expressions they usually evaluate to the last iteration of the loop. From there, the filter/map makes more sense, since it's an expression that evaluates to an array of template-y stuff.
If you see it primarily as a templating langauge, though, the `for` loop makes way more sense — every iteration, it's adding a string to the template.
Like {my_bool && <Component />} instead of (if my_bool then <Component /> else null).
Or {my_bool || <Component />} (which is harder to express in most other languages because of Javascript considering truthy/falsy values instead of boolean true/false).
I am a fan of the UI-as-code approaches (as opposed to UI-as-markup or server-templating approaches) that React has though because of the other arguments you see in this thread, although the syntax could be better for React specifically. Elm is honestly pretty great in my opinion, and Flutter also has a nice language for describing UI as code. React just has less-than-optimal syntax.
I don't have a problem with map, though, except that I would like to extract the mapping function out of the "main view" into its own parameterised function that takes a list of whatever it needs.
As soon as you need a 3rd leg you have to rewrite it as a full blown if/case/whatever anyway.
I think the long history of being served over the wire drove the community to prefer shorter, more terse code.
I think they just looked at the JavaScript example, and realized how ugly/unreadable it was, and said "I can do better", and they did. the Django example is actually clear and readable about whats going on.
the fact that the community converged on the current monstrosity should bring great sadness, not rationalizations.
I helped design the Django template language, where the above would look like this instead:
I do like the type signature aspect of it that you're talking about - I've found myself wanting that for Django templates in the past, to the point that I've started figuring out patterns for populating templates using typed Python dataclasses as opposed to anything-goes-dictionaries.