Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[JSX] Attribute shorthand as es6 Objects #2777

Closed
ghost opened this issue Dec 27, 2014 · 11 comments
Closed

[JSX] Attribute shorthand as es6 Objects #2777

ghost opened this issue Dec 27, 2014 · 11 comments

Comments

@ghost
Copy link

ghost commented Dec 27, 2014

module.exports = React.addClass({
  displayName: 'someName',
  // ...
  render: function () {
    var className = this.state.active ? 'active' : ''
    return <div {className}>...</div>
  }
});

Ecvevalent to

module.exports = React.addClass({
  displayName: 'someName',
  // ...
  render: function () {
    var className = this.state.active ? 'active' : ''
    return <div className={className}>...</div>
  }
});

It's es6 feature http://wiki.ecmascript.org/doku.php?id=harmony:object_initialiser_shorthand
Sorry for my bad English :)

@ToucheSir
Copy link

I'd argue against this, as one would have to consider meaningless statements such as
<div {{prop}}>...</div>. Not sure if this only marginally more terse syntax is worth the possible ambiguity.

Also, jstransform should already allow for the object initializer shorthand outside of JSX attributes.

@ghost
Copy link
Author

ghost commented Dec 27, 2014

@ToucheSir mistakes like that you described, could be done with spread objects, but it was included in core..

@ToucheSir
Copy link

How so? Attempting to use var foo = {...bar, {baz}}, results a notable error in the compilation step. Do you have a specific example demonstrating said mistakes with spread attributes?

@ghost
Copy link
Author

ghost commented Dec 27, 2014

@ToucheSir like this -> <div {...this.props}>..</div>

@bloodyowl
Copy link
Contributor

@vanesyan it's possible with the ES6 option :

<MyComponent {...{item, key}} />

compiles to

React.createElement(MyComponent, React.__spread({},  {item:item, key:key}))

I don't really get why the spread works on props "top-level" while this doesn't, but using an plain object does the job.

ref facebook/jsx#23

@ToucheSir
Copy link

@bloodyowl Good example. Would agree with @RReverser 's reasoning in the linked issue (explicit destructuring is less ambiguous and captures the process more effectively), but I suppose it's a rather subjective matter.

@zpao
Copy link
Member

zpao commented Dec 29, 2014

I feel like we've said no to this with good reason before but I can't find the link. Regardless, the discussion for extending semantics of JSX belongs in the issue @bloodyowl linked to. @sebmarkbage, perhaps you remember where we've talked about this before / can weigh in.

@moretti
Copy link
Contributor

moretti commented Jun 29, 2015

This is something that would be really handy in my opinion.
A lot of my render methods are similar to the following one:

render() {
  const { foo, bar, spam, eggs } = this.props;
  return (
    <div>
      <Component1 foo={foo} bar={bar} />
      <Component2 spam={spam} eggs={eggs} />
    </div>
  );
}

I don't really like using {...this.props}, because I prefer a more explicit way of passing properties down and I wish there was something similar to the ES6 object initializer shorthand.

Too bad that <Component foo /> has a different meaning in JSX 😄

Maybe this alternative is good enough, though:

render() {
  const { foo, bar, spam, eggs } = this.props;
  return (
    <div>
      <Component1 {...{foo, bar}} />
      <Component2 {...{spam, eggs}} />
    </div>
  );
}

@RReverser
Copy link
Contributor

With https://github.com/RReverser/es-borrowed-props proposal, you will be able to:

render() {
  return (
    <div>
      <Component1 {...{ this.props.foo, this.props.bar }} />
      <Component2 {...{ this.props.spam, this.props.eggs }} />
    </div>
  );
}

Until that, I'm afraid, destructuring is your best solution.

@brigand
Copy link
Contributor

brigand commented Jun 29, 2015

It's common to use blacklist for passing props in wrapper components, so you could use the inverse: whitelist.

render() {
  const { foo, bar, spam, eggs } = this.props;
  return (
    <div>
      <Component1 {...whitelist(this.props, 'foo', 'spam')} />
      <Component2 {...whitelist(this.props, {spam: true, eggs: true})} />
    </div>
  );
}
// unreadable example implementation
const whitelist = (obj, ...args) => _whitelist(obj, _flatten(args.map(_whitelistKeys)));
const _whitelistKeys = (x) => typeof x === 'string' ? [x] : Object.keys(x).filter((key) => x[key])
const _whitelist = (obj, keys) => keys.reduce((acc, key) => { acc[key] = obj[key]; return acc }, {}) ;
const _flatten = (xss) => Array.prototype.concat.apply([], xss);

It's probably best to solve this outside react, like blacklist, classnames, and other similar useful modules.

@zpao
Copy link
Member

zpao commented Jul 10, 2015

We're deprecating our own JSX transform so going to close this out.

@zpao zpao closed this as completed Jul 10, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants