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: Allow multiple JSXElement in PrimaryExpression #58

Closed veged closed 2 years ago

veged commented 8 years ago

It will be useful if JSX extends the PrimaryExpression in this way:

That enables us to use multiple JSXElement's on the top level. And transpilers can transpile this to array of elements.

For example in React JSX we gonna be allowed to do:

render() {
  return <span>{ this.renderContent() }</span>
}

renderContent() {
  return (
    <em>1</em>
    <strong>2</strong>
  )
}

Right now we have to do:

renderContent() {
  return [
    <em key="1">1</em>,
    <strong key="2">2</strong>,
  ]
}

Note the commas and keys.

veged commented 8 years ago

cc @dfilatov

syranide commented 8 years ago

This is essentially fragments, but IMHO a very poor way of doing it. There's no way to have text or expressions as the first or last child with this syntax (or even in the middle, as it is written now). It's also ambiguous; <A/><B while not very meaningful it is still a valid expression, with this proposal then <A/><B/> would overlap.

syranide commented 8 years ago

To illustrate, the following workaround (albeit a bit ugly) supports all use-cases without introducing new syntax. Simply reserving a tag name and translating it to be a fragment would be enough, but it's not entirely obvious to find a specific keyword that everyone is ok sacrificing or which alternate syntax you would want (<!></!> or w/e).

return (
  <x>
    <em key="1">1</em>
    <strong key="2">2</strong>
  </x>.props.children
);
dfilatov commented 8 years ago

@syranide workaround looks even more ugly than using array

dy commented 5 years ago

@veged that also provides natural JSXFragment syntax. It would be nice to have this instead of <>...</>

zmrhaljiri commented 5 years ago

Can anyone please explain why exactly it's needed to put just single element/fragment to the return() function and returning adjacent elements is not possible?

I mean:

// in the past
return (
    <div>
        <p>Hi</p>
        <p>Hi</p>
    </div>
)

// now
return (
    <>
        <p>Hi</p>
        <p>Hi</p>
    </>
)

// possible future?
return (
    <p>Hi</p>
    <p>Hi</p>
)

Cannot the return() function automatically insert fragment if it finds that more than one element is returned? If not, why?

Also, if it's really not possible, why Babel cannot do this? It can transform anything so maybe it can also solve the condition "if multiple elements are returned then wrap an output with a fragment".

I'd like to have this explained since this wrapping always seemed unnecessary and annoying to me. So I'm just curious if this really cannot be changed :)

mindplay-dk commented 4 years ago

Looks like PrimaryExpression has been changed to JSXElement | JSXElementFragment in master now?

I discovered by accident that multiple JSX expressions suddenly just worked on codesandbox, so it looks like this change is already being implemented - though I can't seem to find any official announcement of this anywhere (?)

Anyhow, I suppose this issue can be closed?

Huxpro commented 2 years ago

Thanks for the proposal. I think by now JSXFragment had already fulfilled this feature requirements. Closed.