<div>
<h1>Conditional Display and Looping in JSX</h1>
<ul>
{this.state.items.map(item => (
item.show ? <li key={item.id}>{item.name}</li> : null
))}
</ul>
</div>
That seems like such an unintuitive way of implementing loops and if statements!I helped design the Django template language, where the above would look like this instead:
<div>
<h1>Conditional Display and Looping in Django Template</h1>
<ul>
{% for item in items %}
{% if item.show %}
<li>{{ item.name }}</li>
{% endif %}
{% endfor %}
</ul>
</div>
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.- 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.
So I'm extending the language to feature statically typed string templates as well. It currently targets (generates) C++, but I'll add other language targets in the future.
It's still a work in progress but I just flipped the repository public in case you want to follow along as I work: https://github.com/dpemmons/typedef
Yeah exactly, which is why I always recommend DSLs that embed HTML directly in the language. E.g. https://com-lihaoyi.github.io/scalatags/ or (my own) https://github.com/yawaramin/dream-html
They make writing HTML a breeze with the full power of the programming language available.
> We were doing this the same year that React came out, and clearly had some of the same thoughts as Dan Abramov did
Dan Abramov is not the original creator of React. That was Jordan Walke: https://www.youtube.com/watch?v=GW0rj4sNH2w
With most templating languages, there is no defined function signature (with arguments and types specified), so you get to read through the template to figure out what data to pass in. This makes it very hard to make things reusable. And similarly, templating languages are often some bizarre, janky custom language with pipes and stuff.
At a previous employer, we actually solved this problem. We implemented a pattern that gave us real typed interfaces for UI components rendered with templates on the server. We were doing this the same year that React came out, and clearly had some of the same thoughts as Dan Abramov did, although not in the browser.
I recently started a side-project in javascript for the first time in years, and was surprised to discover that there is apparently no modern open-source library for rendering server side components, other than rendering react on the server of course. Your options are basically react or using some shitty templating language. I went with react.
1: When I say react, please understand it to mean any of the nice modern frontend libraries, like react, vue (is this still a thing?), svelte, etc.