Skip to content

Conversation

calebmer
Copy link
Contributor

@calebmer calebmer commented Jul 13, 2016

The JSX syntax has been changed as of facebook/jsx#59

In addition to this PR there is another PR open to babylon here: babel/babylon#42

For more information about the initial proposal see: facebook/jsx#57

cc @kittens, @danez

@sebmck
Copy link
Contributor

sebmck commented Jul 13, 2016

Could we update the JSX transform to support this too?

@calebmer
Copy link
Contributor Author

calebmer commented Jul 13, 2016

@kittens the React JSX transformer? I can do that, but as I understand it the React team (@syranide and @sebmarkbage) considers this an antipattern. The target for these PRs is really more for general JSX transformers like babel-plugin-transform-jsx.

Here’s what I’ll do. In order to keep the React transformer spec compatible I won’t throw an error at spread children, but instead treat a spread child the exact same as any other child. This means non-iterables may also be “spread” with no other effects. Example:

<div>{a}{...b}</div>
React.createElement('div', a, b)

(even if b is not an iterable)

@syranide, @sebmarkbage is this something you’re comfortable with? Would you prefer an error to be thrown?

@kittens Also, the tests aren’t passing. Is this because babel/babylon#42 hasn’t been published or is this an error I need to debug?

@syranide
Copy link

syranide commented Jul 13, 2016

Here’s what I’ll do. In order to keep the React transformer spec compatible I won’t throw an error at spread children, but instead treat a spread child the exact same as any other child. This means non-iterables may also be “spread” with no other effects. Example:

@calebmer @sebmarkbage is definitely the authority on this. But IMHO that seems wrong, spreading in this context should intuitively mean that they all end up in the same children array (such that the indices also become sequential). Effectively, <div>{...childrenA}{...childrenB}</div> === <div>{concat(childrenA, childrenB)}</div> (not exactly, but you get the idea), this does not hold for your definition. Not saying it's very useful, but that's what it should mean as far as I understand it.

If the behavior differs from this it seems better to throw as ... has no purpose and is not going to do what you expect it to do.

EDIT: Updated incorrect example.

@sebmck
Copy link
Contributor

sebmck commented Jul 13, 2016

Ah okay. It is up to the React team if they want to support it in their flavor of JSX. If they decide against it I'd ask that we throw an error when attempting to transform it.

@syranide
Copy link

syranide commented Jul 13, 2016

If my definition is sound then it shouldn't technically be a problem to implement it, but it will probably make the transform unnecessarily complicated and from my perspective I doubt anyone would ever use it with React (and benefit from it rather than have shot themselves in the foot). Perhaps @sebmarkbage has some thoughts on this.

@calebmer
Copy link
Contributor Author

Just for some context, Babel currently transforms this:

const a = 1
const b = 2
const c = [a, ...b]

…to this:

"use strict";

function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }

var a = 1;
var b = 2;
var c = [a].concat(_toConsumableArray(b));

(REPL link)

@danez
Copy link
Member

danez commented Aug 16, 2016

Can we decide on what todo on this (because we would like to release babylon)? Reading through the discussion it seems we should throw an exception.
Which is also more safe for the future, instead of deciding something now. In the case the react team decides it wants to have some behaviour when using spread in future we could simply add it as new feature and not have to do all the bc or create a new major version of babel, because we would already have some other behaviour that we decided now.

//cc @sebmarkbage

@sebmarkbage
Copy link

Yea, let's throw if it is being used with the React transform. It is a foot gun for now. Might as well disable it.

@calebmer
Copy link
Contributor Author

What’s the status on this? If you were waiting for me to implement the errors, sorry I missed that 😉

What needs errors? babel-plugin-transform-react-jsx-compat, and babel-plugin-transform-react-jsx correct?

@manvalls
Copy link

manvalls commented Nov 3, 2016

I've got this working on my own babel plugin. I've modified the code here to include the following:

function buildElementCall(path, file) {
  path.parent.children = t.react.buildChildren(path.parent);

  for(let i = 0;i < path.parent.children.length;i++){
    if(path.parent.children[i].type == 'JSXSpreadChild'){
      path.parent.children[i] = t.spreadElement(path.parent.children[i].expression);
    }
  }

  // ...

}

It does what it's supposed to do for the concrete purposes of my plugin. The thing is: will this likely break with future babel-related packages versions?

@jridgewell jridgewell mentioned this pull request Dec 11, 2016
@hzoo hzoo closed this in #4988 Dec 16, 2016
@lock lock bot added the outdated A closed issue/PR that is archived due to age. Recommended to make a new issue label Oct 6, 2019
@lock lock bot locked as resolved and limited conversation to collaborators Oct 6, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
outdated A closed issue/PR that is archived due to age. Recommended to make a new issue
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants