facebook / react

The library for web and native user interfaces.
https://react.dev
MIT License
229.19k stars 46.91k forks source link

className prop not working with custom DOM elements in 0.14.0-rc1 #4933

Closed hellosmithy closed 8 years ago

hellosmithy commented 9 years ago

The className prop does not appear to get mapped correctly when applied to custom DOM elements in 0.14.0-rc1.

JSFiddle: https://jsfiddle.net/hellosmithy/5pdujnfq/1/

hellosmithy commented 8 years ago

@jimfb hmmm well I guess this comes down to difference of opinion but to me the escaping solution seems both more intuitive and more future-proof.

  1. Intuitive in that it is the same behaviour as is used elsewhere with DOM elements. The difference in behaviour based on the hyphenated vs non-hyphenated element names on the other hand seems completely counterintuitive, especially given there was a precedent of it working the former way.
  2. More future-proof in that it keeps control with the developer. A single attr would need to be whitelisted eg. setAttrs as a straw-man example, but if a developer wanted to use that very same attr for a web component they would still be able to. I can't see how it would cause issues with https://github.com/facebook/react/issues/140.
mikeybox commented 8 years ago

@jimfb I'm not sure why having a setAttr prop for attribute mapping wouldn't support all the constraints? It seems like it would be the most likely fit

Must be intuitive for users. Ideally, the first thing people try should work. If it doesn't work, users must have an obvious "next step" to try so they can fix their code (ie. what happens when an attribute they wanted to use gets rewritten? do they get a useful error message? how do they intuitively know what to try next?).

If you have an attribute not currently supported by the current list of html attributes then the next step would be to find a way to manually set attributes. We already know that we can set HTML it wouldn't be much of a leap to assume theres a function for attributes and hey thats why we have documentation.

Should play nice with #140 and futureproof us from maintaining an ever-growing whitelist as browsers add new elements/attributes.

theres no need to place an arbitrary behaviour on dashes in tag names. The w3 standard already declares that custom elements are not special in themselves and should be treated as such. In their basic form they're merely naming convention. React already supports the official list of attributes and while it may change and update over time that would be a problem with standard dom behaviour as it is. The only real solution to that would be to remove the ambiguity between object props and string attributes.

jimfb commented 8 years ago

This thread has been going on way too long, and is circling back to points that I've already made previously in the thread. I don't think it's useful to keep rehashing this issue.

  1. Rendering exactly what the user typed is intuitive because a user can type className, see that it literally outputted className, and then try class (because, well, it appears to be outputting exactly what they typed) and see that it works. It doesn't take long to realize the pattern that custom elements get outputted directly, but even if you do miss the pattern, you'll quickly arrive at the correct solution through a single trial-and-error attempt. With an escaping solution, you would type className, it would get rewritten to class, and you would not have any intuitive way of knowing that the magic escape prop you need to use is called setAttrs.
  2. No, the whitelisting would be extensive. You would need to whitelist className, htmlFor, value, all the other dom attributes that have boolean values and/or otherwise behave in intelligent ways, all the dom properties that would need to be applied as a property instead of an attribute, all the various dom event handlers, etc.
mikeybox commented 8 years ago

@jimfb what we're already seeing is that the change between standard DOM elements and custom element behaviour is counter intuitive and thats the point being made. You'd assume currently that using className would output class because thats what happens everywhere else. Suddenly the behaviour changes because of a dash in the element name which is arbitrary. You're assuming that the use of a dash means I want to create a web component that is going to have special handling of attributes. It's currently counter intuitive which is why it keeps going around in circles. It seems like the extensive whitelisting is a result of the behaviour change added to custom elements where all props are mapped.

It's clear we all care about this stuff because react is probably the coolest framework around and we use it every day. So yeah people are going to get passionate about it because its so important. Whats important especially to us is the use of custom elements as standard html elements using the current 0.13 behaviour that had no prejudice between elements. All were equal. What we're saying is that the non-equality proposed should be done using a setAttr rather than the current behaviour forking which seems wrong.

hellosmithy commented 8 years ago

@jimfb I wonder if we're talking at cross-purposes here. If we're circling back I think it's because the points are being disputed which seems reasonable enough. And to echo @mikeybox it's because we care about keeping React the great project that it is.

Rendering exactly what the user typed is intuitive because a user can type className, see that it literally outputted className, and then try class

I can't speak for others but I can say that this certainly wasn't intuitive for me as I debugged this after upgrading to 0.14.0-rc1 and it seemed like a bug.

the whitelisting would be extensive. You would need to whitelist className, htmlFor, value, all the other dom attributes that have boolean values and/or otherwise behave in intelligent ways

What we're suggesting is to not make an arbitrary disctinction. So why would there be any extra whitelisting other than the single point of entry for setting escaped attrs? The suggestion is simply that <custom-elem> by default behaves the same as <div> or <span>. In fact the behaviour worked exactly this way before, just without the extra ability to set some kind of escape attr for those that do want to connect to external web-component APIs.

jimfb commented 8 years ago

Ok, I think it's time to call it a day. We've had a pretty good discussion, but this conversation is looping back on its self and is past the point of being productive. The thread is just rehashing points that have already been made. I think we fully understand the concerns mentioned in this issue, and we will update the thread when we have new information to provide.

braden-qualtrics commented 8 years ago

Any thoughts on whether or not this (http://stackoverflow.com/questions/37638268/can-i-put-underscores-in-my-html-tagnames) is a reasonable work around for now?

jimfb commented 8 years ago

@braden-qualtrics Sounds like a bad idea to me. You're going to hit all kinds of edge cases that are going to bite you. Cases that our current design/support of custom elements is specifically designed to help you handle, as described earlier in this thread.

braden-qualtrics commented 8 years ago

@jimfb So using underscores in element names might break React/HTML?

gaearon commented 8 years ago

I'm closing since this is not a bug, but a different (and now documented) behavior for web components. Use class for them.

sebmarkbage commented 8 years ago

This might be related to #7901. If we make a breaking change to switch to properties then this would become className.