AlexGilleran/jsx-control-statements

Trivial else (suggestion/enhancement)

lalomartins opened this issue · 7 comments

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 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 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 .

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 . 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 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...