3

Having something like this

this.props.colour = 'red'
<MyComponent {…this.props} colour="blue">

or this

<div className="red" className="blue"></div>

which are admittedly weird, breaks your site on IE. I got a completely blank page, which seems a pretty harsh response.

The actual error is

SCRIPT1046: Multiple definitions of a property not allowed in strict mode

which is documented here.

Chrome and FF seem to handle that just fine by ignoring the first declaration.

Are there any React docs I missed pointing to this behaviour?

U r s u s
  • 6,680
  • 12
  • 50
  • 88
  • This is a restriction that absolutely makes sense but was nonetheless loosened in ES6 because of computed properties. That's why it works in Chrome, but not in browsers that implement the (correct but) outdated behaviour. In conclusion, just don't do it. – Bergi May 27 '16 at 11:27
  • Thanks @Bergi. If you don't mind writing up your comment as an answer, expanding on why it's been loosened in ES6 and adding a reference to a doc or something, I'll happily accept it. Just in case someone else stumbles on it. – U r s u s May 27 '16 at 11:32

3 Answers3

3

Are there any React docs I missed pointing this odd behaviour?

No, this doesn't have much to do with React. It seems that the jsx syntax is transpiled to object literals, and so their property rules apply for attributes as well.

IE throws Multiple definitions of a property not allowed in strict mode, but Chrome and FF seems to handle that just fine by ignoring the first declaration.

This is a restriction that absolutely makes sense but was nonetheless loosened in ES6 because of computed properties - see What's the purpose of allowing duplicate property names? for details. That's why it works in Chrome, but not in browsers that implement the (correct but) outdated behaviour.

In conclusion, just don't do weird things and it won't behave weirdly.

Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
0

It does not make sense to have multiple identical attribute keys in XHTML, this is considered an error in XML, and thus it was also spread to HTML which looks a lot like XML but is less strict. This is just how XML works. You have the same behavior with JSON, keys must be unique at a given level of the tree.

Personally I think those limitations are sane and allow to automatically verify documents if you use XHTML, others prefer it more flexible and less strict.

Christophe Roussy
  • 16,299
  • 4
  • 85
  • 85
0

Not an answer to why it breaks on IE, but a recommended approach for dealing with multiple classNames.

Use the classnames package (https://github.com/JedWatson/classnames).

npm install classnames --save

Then you could use it like so:

import styles from './styles.scss';
import classNames from 'classnames';

function MyComponent(props) {
  // we could possibly receive a class from outside the component
  // as a prop.
  const propClassName = props.className;

  // We use `classNames` function to merge two classnames. 
  return (
   <div className={classNames(styles.root, propClassName)}>
     Hello world
   </div>
  )
}

This way you will still have multiple classes applied to your component without a duplicate prop declaration. If the case above, if the passed in prop is nil then only the styles.root class is applied.

Check out the rest of their docs, you can do some cool things with classnames, like enable a class based on a bool flag etc.

e.g.

const fullClassName = classNames(
  styles.root,
  { 'active': props.active }
);

In the example above the "active" class will only be applied if props.active is truthy.

You can also use a class from the imported stylesheet using ES6 computed property names. For example:

const fullClassName = classNames(
  styles.root,
  { [styles.active]: props.active }
);

As you can see, this opens up a ton of customisation options to your components.

ctrlplusb
  • 12,847
  • 6
  • 55
  • 57