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

No reason for JSX to deviate from HTML #2782

Closed
taoeffect opened this issue Dec 29, 2014 · 15 comments
Closed

No reason for JSX to deviate from HTML #2782

taoeffect opened this issue Dec 29, 2014 · 15 comments

Comments

@taoeffect
Copy link

So my understanding from #2781 is that there is no legitimate reason for JSX to prohibit JavaScript keywords, and for the same reasons there is no reason to require camelCase attributes.

This appears to be an oversight on the part of the original authors.

As far as fixing this goes, the concern expressed appears to be backwards compatibility. As far as I can tell, there doesn't seem to be any reason why someone couldn't submit a PR that is fully backwards compatible with today's JSX, and allows coders and designers to use HTML naturally (something that could be a major boon to the project as well).

Within 30 minutes of opening issue #2781 two people (@antoinegrant and @akiran) 👍'd it.

It seems like something many people want, myself included. For me, also, whether or not this is allowed to be fixed indicates the health of project. Something is very obviously broken and people are being asked to jump through unnatural hoops for absolutely no reason.

If that's not enough reason to fix something in React then why should anyone continue to recommend the project?

To the group members and project admins, I just ask that you give this issue some honest thought for at least 5 minutes before hitting the close button. And if you still decide to close the issue, please let the community know your reasoning so we can understand why.

Thank you,
Greg Slepak

@gaearon
Copy link
Collaborator

gaearon commented Dec 29, 2014

I think you're missing the point here. (Note that I'm not a maintainer, just a user like you.)

JSX is not HTML and trying to make it look almost like HTML will be worse IMO. Its semantics will always be different (e.g. special “merging” behavior for style property, which btw is an object and not string like HTML). Whitespace handling is quite different (and much more practical). If it looks exactly like HTML, people will expect it to behave like HTML, which it doesn't (and shouldn't).

If attribute names were lowercase, then there would be inconsistency in how you declare you own component's props and DOM props:

<MyComponent someProperty='lallaa' someOtherProperty={5}>
  <a tabindex={5}>

Doesn't this look weird? By the way, HTML lets you use any casing, not just lowercase. Would you like JSX to behave like this as well? But props are keys on plain JS objects, and JS object keys are case-sensitive. How would that work with custom components?

For me, also, whether or not this is allowed to be fixed indicates the health of project. Something is very obviously broken and people are being asked to jump through unnatural hoops for absolutely no reason.

What do you call jumping through unnatural hoops? JSX is not HTML, it's a domain specific language for describing DOM trees. It happens to have a lot in common with HTML, but there is no practical upside to making it more similar to HTML, and there are a lot of downsides (HTML is less expressive).

@taoeffect
Copy link
Author

OK, fair point regarding that some deviation is required to distinguish between Components and HTML tags (using capital first letter to indicate component).

But what reason is there to deviate beyond that?

@gaearon
Copy link
Collaborator

gaearon commented Dec 29, 2014

What about attributes? As I said, lowercase attributes would be weird in JS code (your model objects would probably be camel case anyway, and then you get inconsistency like this.props.somedata.someProperty). If we use camelCase for “custom” component attributes, you get inconcistency between casing for custom and DOM component attributes.

To reduce inconsistency, React enforces certain rules that make JSX more like JS and less like HTML. Which makes sense because it can't have HTML semantics. For example, it can't have self-closing tags or browser's behavior for tags like p (where closing tag can be omitted), because this would mean re-implementing a whole HTML parser and calling it each time before diffing DOM. This would be very inefficient.

On the other hand, if you try to think that JSX obeys rules of JS and not so much HTML, the decisions taken by React team begin to make sense.

@jefffriesen
Copy link

I'm not a maintainer nor do I really have a strong opinion one way or another on this issue, but practically it's been really simple to use JSX. If I ever have chunks of HTML that needs converting, I just run it through an HTML to JSX converter like this: http://facebook.github.io/react/html-jsx.html

@akiran
Copy link

akiran commented Dec 29, 2014

What if we make changes in JSX transformer while keeping same semantics in js ?
class in jsx can be transformed className in js
hyphenated attributes in jsx can be transformed to camel case attributes in js.

angular.js does similar thing
In angular templates we can use hyphenated attributes and camelCased attributes are available for access in angular directives.

@gaearon
Copy link
Collaborator

gaearon commented Dec 29, 2014

hyphenated attributes in jsx can be transformed to camel case attributes in js.

What would be the point of this? You lose greppability of props (have to grep both versions each time), you still get inconsistency between twowords (HTML style) and two-words (style you're suggesting), you lose spread attributes (can no longer do <div {...this.props.componentProps}, or you'd have to leak this hyphenated-attribute convention into JS objects as well, and for what?

You're trading real consistency for a false feeling of familiarity.

@wildfiremedia
Copy link

Those with Apache Flex or Actionscript background have not problem with JSX
since they're somewhat similar.

On Mon, Dec 29, 2014 at 11:08 PM, Dan Abramov [email protected]
wrote:

hyphenated attributes in jsx can be transformed to camel case attributes
in js.

What would be the point of this? You lose greppability of props (have to
grep both versions each time), you still get inconsistency between
twowords (HTML style) and two-words (style you're suggesting), you lose
spread attributes (can no longer do <div {...this.props.componentProps},
or you'd have to leak this hyphenated-attribute convention into JS objects
as well, and for what?

You're trading real consistency for a false feeling of familiarity.


Reply to this email directly or view it on GitHub
#2782 (comment).

@zpao
Copy link
Member

zpao commented Dec 29, 2014

I can assure you this is not an oversight. We talked about this ad nauseum. As for giving it 5 minutes… we've given it 2 years. This is a design decision and not a bug.

class in jsx can be transformed className in js

We actually did that initially but it takes away from real uses cases where you want class to be the prop. Remember, Composite Components are a vital part of React, not just DOM components. For example <Teacher class="Physics" />. Transforming that to React.createElement(Teacher, {className: "Physics"}) is a terrible idea. It's super surprising and entirely outside of the programmer's control. Inside the Teacher component, you should access props as they are specified.

The same goes for the hyphenated -> camelcase idea. You're specifying values one way and reading them another.

Keeping the JSX transform as simple as possible is a real goal.

We're not going to support something just because a couple people 👍 it. We're opinionated here. We're happy to be unpopular with a few people if we ultimately think what we're doing is right. On the other hand we're not so confident that we won't listen to people saying we've made mistakes. But in this case we've spent a lot of time thinking about it and we're not going to change.

@zpao zpao closed this as completed Dec 29, 2014
@taoeffect
Copy link
Author

@gaearon wrote:

If we use camelCase for “custom” component attributes, you get inconcistency between casing for custom and DOM component attributes.

If I'm understanding you correctly, that is a good thing, and all the more reason to do this, because it helps make clear the distinction between React components and DOM nodes.

@zpao wrote:

As for giving it 5 minutes… we've given it 2 years.

Don't say that, because you haven't, and that would be a lie.

You apparently haven't given it even one minute's worth of thought, as demonstrated by your complete and total misunderstanding of the example I gave (as though you didn't even read it):

it takes away from real uses cases where you want class to be the prop. Remember, Composite Components are a vital part of React, not just DOM components. For example . Transforming that to React.createElement(Teacher, {className: "Physics"}) is a terrible idea.

Yeah, good thing nobody was suggesting that.

Sorry, clear to me now that React is run by folks with short attention spans and poor design decision making faculties.

Was hoping to like it, because other aspects of the project I do like very much (its simplicity over AngularJS, but then again, everything is simple compared to AngularJS).

:-\

@zpao
Copy link
Member

zpao commented Dec 29, 2014

Calling somebody a liar really doesn't get you far. FWIW, we've talked about exactly this topic many times over the last 2 years, and that's the truth.

Yeah, good thing nobody was suggesting that.

That was suggested: #2782 (comment)

as demonstrated by your complete and total misunderstanding of the example I gave (as though you didn't even read it):

Below is the only example I've seen from you, from #2781:

var root = React.createElement('ul', { className: 'my-list' }, child);

As far as examples go, it really doesn't give me much to go from. You said you want to use class there instead of className and I explained why we don't do that. The reason provided there applies more broadly across other properties.

If you're going to continue being hostile and insulting me, my team, and the other helpful people we work with, I'm going to ask you to remove yourself from any involvement with the project.

@taoeffect
Copy link
Author

That was suggested: #2782 (comment)

My mistake, I didn't see that (that wasn't what I was suggesting).

Below is the only example I've seen from you, from #2781:

var root = React.createElement('ul', { className: 'my-list' }, child);

My example was saying that instead of that you would simple use 'class'.

However, I just saw your new comment in #2781 posted 5 hours ago. Thanks for that, that clears things up, and those are actually better reasons than the ones I saw before.

If you're going to continue being hostile and insulting me, my team, and the other helpful people we work with, I'm going to ask you to remove yourself from any involvement with the project.

You brought this hostility upon yourself through how you responded to very polite and patient attempts at discourse.

Maybe next time try to actually engage in conversation with folks and understand their POV instead of closing issues without any serious and honest engagement.

@gaearon
Copy link
Collaborator

gaearon commented Dec 29, 2014

because it helps make clear the distinction between React components and DOM nodes.

And why would you want that distinction? I find myself often making tiny wrappers around DOM components that proxy most props but have some custom logic. Which convention would I choose for tabindex prop of my custom FlexibleTextArea which wraps a textarea?

I suggest you try to actually use React in a real project for a couple of months and make dozens of components. This will help you adjust perspective (vs initial impressions) and maybe see some value in the consistency of current design.

It's sad that you assume that people disagree with you because they're ignorant, stubborn or liars.

@taoeffect
Copy link
Author

Which convention would I choose for tabindex prop of my custom FlexibleTextArea which wraps a textarea.

The one that works?

It's sad that you assume that people disagree with you because they're ignorant, stubborn or liars.

Sad that you assume that was case.

@gaearon
Copy link
Collaborator

gaearon commented Dec 29, 2014

It would help if you clarified what you're advocating. Hyphenated attributes? HTML-style attributes?

@zpao
Copy link
Member

zpao commented Dec 29, 2014

🔒

@facebook facebook locked and limited conversation to collaborators Dec 29, 2014
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants