jsx-control-statements
jsx-control-statements copied to clipboard
Trivial else (suggestion/enhancement)
I find I have a common pattern of
<Choose>
<When condition={foo}>one-liner</When>
<Otherwise>
a lot of stuff
</Otherwise>
</Choose>
It kind of makes me want to just use a ternary; the control statements are neither succinct or clear/intent-expressive.
The one-liner in question will be a marker for “field not present”, an icon, a <NotFound/> component, and in some cases even a single space.
An alternative which I think would make sense is something like:
<SomeControlTag condition={!foo} someprop="one-liner">
a lot of stuff
</SomeControlTag>
While having jsx in props looks weird, it's completely valid, and I've used it a couple of times with react-bootstrap stuff. I wouldn't recommend it for longer values, but it's fine for short stuff. So, you could in fact also have, someprop={<NotFound/>}
.
Now, assuming this is a good idea at all, what does the actual tag and prop look like?
My first instinct was to add this to <If>:
<If condition={!foo} else="one-liner">
The problem should be obvious though… having “else” before “then” feels really odd. But I don't know if that objection is strong enough to justify loading the namespace with a new tag that does mostly the same thing as <If>.
Here's a weird alternative, I don't like but I'll write it down anyway:
<If condition={foo} then="one-liner" else>
stuff
</If>
Anyway. Please discuss 😺
Thanks for the request! Are the one-liners usually strings or very simple statements though? Unless I'm missing something you could do all your examples pretty easily with a custom component, react-if
style.
You're thinking only of the one-liner, the “lots of stuff” part will be more complex and I wouldn't want it to evaluate if the condition is true (or false in the inverted syntax case).
Ah yeah that's true, but I still find it kinda weird. Happy to hear thoughts from others.
In my opinion the succinct version would be the flat if-else.
<If condition={foo}>
a lot of stuff
</If>
<Else>
one-liner
</Else>
Discussion #32
Yeah, that would in theory work for me, but I can also understand the objections of “non-xml-ness”. This one is legal on the parser level, and won't break lints.
For me if it gets complex enough — if both branches have jsx beyond a single self-closer, or any js more complex than you could fit in half a line — you're better off with <Choose>. This would be really an abbreviation for a case that, at least for me, is common… and it's not because I'm lazy, but because the full <Choose> construct really obscures the code.
BTW I do have a modicum of experience in this sort of stuff, which is why I became interested 😉 in 1999 I co-designed the second-gen Zope template language (ZPT), which compared to the old one was a move in the direction of more standard XML. Just to contextualise where I'm coming from…
So. After a few days thinking about this (and a bit of reading through old issues)… I think <Else>
doesn't really need to be killed, we just have to do it more XML and less Handlebars.
<If condition={foo}>
bar
<Else>qux</Else>
baz here is technically legal too but discouraged
</If>
Then the old syntax can be supported for compatibility… although, I suppose that's what major versions are for, at some point (4.0.0?) it can be dropped.
As for the “trivial” bit, I'd favour making both then
and else
accepted as pseudo-prop.
<If condition={wantFoo} then="foo" else="bar"/> {/*legal*/}
<If condition={wantFoo} else={<NotFound/>}>foo</If> {/*legal but weird but legal*/}
<If condition={wantFoo} else="bar">foo<Else>bar</Else></If> {/*not legal*/}
<If condition={wantFoo} then="foo" else="bar">qux</If> {/*not legal*/}
<If condition={wantFoo} then="foo">bar</If> {/*not legal?*/}
<If condition={wantFoo} then="foo" else>bar</If> {/*legal???*/}
I don't think that the deprecated Else-Syntax needs to be revived. In your suggested version it is not as readable as it should be: <If>
and <Else>
should be on the same indentation level. The XML-way is <choose>
and works like that in XSL-T.
Regarding the abbreviated syntax, you already name the counter-argument: Edge cases which make less and less sense. Additionally, one of the most prominent React arguments is: Keep the API surface as small as possible. And React really lives up to this mantra, if you think about it.
I'm also not convinced that writing
<If condition={toBeTested} else="Just a result string!">
...
</If>
is more readable than, e.g.
<If condition={toBeTested}>
...
</If>
<If condition={!toBeTested}>
Just a result string!
</If>
From my point of view I would always expect the else branch on the same level as the if branch. I can't imagine that users wouldn't be confused by the abbreviated syntax...