facebook / jsx

The JSX specification is a XML-like syntax extension to ECMAScript.
http://facebook.github.io/jsx/
1.96k stars 133 forks source link

Proposal: implicitly use do-expression for any JSX expr container #39

Open RReverser opened 9 years ago

RReverser commented 9 years ago

I just saw this tweet: https://twitter.com/vslinko/status/619581969903550464

And wondering if there are any downsides or backward incompatibilities to enabling do-expression over any JSX expression container so that if and other statements could be used directly inside of braces? My understanding is that for regular expression do { ... } will preserve compatibility and thus wrapping will just enhance contents to support statements as well.

@vslinko @sebmarkbage @jeffmo @wycats @sebmck

chicoxyzzy commented 9 years ago

ref https://github.com/rwaldron/tc39-notes/blob/master/es6/2014-01/jan-29.md#do-expression

sebmck commented 9 years ago

I can implement this in Babel with literally a few lines so :+1: from me. Also see reactjs/react-future#35 which is the exact issue that prompted that tweet and discussion :smile:

vslinko commented 9 years ago

@sebmck My tweet inspired by your comment :smile:

RReverser commented 9 years ago

Haha, circle has closed :) (I didn't see the original discussion; sorry @sebmck)

syranide commented 9 years ago

My main objection would be that if this makes sense... then it should make sense for fat-arrow functions as well, if they choose not to have it JSX probably shouldn't either.

sebmarkbage commented 8 years ago

To follow up. This is still an open issue, but not very high priority until do expressions are further along the standardization track and its semantics clarified.

sebmarkbage commented 8 years ago

@syranide I'm not sure it is obviously so. Would you care to elaborate? Do you mean fat-arrows with the block or single expression? Regardless, fat-arrows don't do this.

I think the rationale may be different since it is a late executing block. For example, control flow like return, break, continue... behaves very differently in these cases.

They're also standardized in different order so this could be a process artifact rather than technical rationale.

sebmarkbage commented 8 years ago

What does {x:1} mean in a do expression body? Is it a block with a label or an object literal? If it's a block, it is unfortunate that {{ }} wouldn't work to create an object. You would have to use {({ })}.

RReverser commented 8 years ago

@sebmarkbage Huh, you're right. Everything inside of the do expression, incl. {x:1} is a block. Might be a serious issue for us.

syranide commented 8 years ago

@sebmarkbage @RReverser That's how arrow functions work too. PS. And having object children seems like something that is rarely useful.

RReverser commented 8 years ago

@syranide I still fail to see why you compare arrow functions to do expressions. They were designed as functions after all, so they had to be able to provide code blocks that don't return any values but behave pretty much as regular functions/blocks. Do expressions are different in the sense that their entire point is exactly to implicitly return last value. Arrow functions don't need to adopt this implicit behavior by default, but do expressions complement them in the sense that you can do x => do { ... } when it's needed.

ghost commented 6 years ago

This seems like a good idea at first glance but I'm concerned it encourages spaghetti code.

I can't think of a use case that couldn't already be implemented in a better way, predominantly through encapsulation. In simple cases bool expressions are fine (the classic {foo && <bar foo={foo} />}), in more complicated cases encapsulation provides cleaner code and better reusability (for better or worse).

Taking the example from the linked tweet in the original post, we can tidy it up through encapsulation as:

function UserMenuItem(props) {
  return props.user ? <UserInfo user={user} /> : <LoginForm />;
}

class Menu {
  render() {
    return <div>
      <h2>Menu</h2>
      <UserMenuItem user={this.props.user} />
    </div>;
  }
}

We could go a step further and make Menu itself a function-style component, further simplifying the code.

graingert commented 5 years ago

{foo && <bar foo={foo} />} is buggy, if foo is undefined then React will warn.

You need {foo && <bar foo={foo} /> || null} in which case you might as well use ternary:

{foo ? <bar foo={foo} /> : null}