为什么在 IE 上多次声明 className 会破坏应用程序?

Why do multiple declarations of className on IE breaks app?

有这样的东西

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

或这个

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

这确实很奇怪,会破坏您在 IE 上的网站。我得到一个完全空白的页面,这似乎是一个非常严厉的回应。

实际错误是

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

记录在案 here

Chrome 和 FF 似乎通过忽略第一个声明来处理这个问题。

有没有我遗漏的 React 文档指出这种行为?

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

不,这与 React 没有太大关系。似乎 jsx 语法被转换为对象文字,因此它们的 属性 规则也适用于属性。

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.

这是一个绝对有意义的限制,但由于计算属性,在 ES6 中仍然放宽了限制 - 有关详细信息,请参阅 。这就是为什么它在 Chrome 中有效,但在实现(正确但)过时行为的浏览器中无效。

总之,只要不做奇怪的事情,它就不会表现得很奇怪。

在 XHTML 中有多个相同的属性键是没有意义的,这在 XML 中被认为是一个错误,因此它也被传播到 HTML 看起来很像 XML 但不那么严格。这就是 XML 的工作原理。 您与 JSON 有相同的行为,键在树的给定级别必须是唯一的。

我个人认为这些限制是明智的,如果您使用 XHTML,可以自动验证文档,其他人更喜欢它更灵活,更不严格。

不是它为何在 IE 上崩溃的答案,而是处理多个 class 名称的推荐方法。

使用 classnames 包 (https://github.com/JedWatson/classnames)。

npm install classnames --save

然后你就可以这样使用了:

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>
  )
}

这样您仍然可以将多个 class 应用到您的组件,而无需重复的 prop 声明。如果是上述情况,如果传入的 prop 为 nil,则仅应用 styles.root class。

查看他们的其余文档,您可以使用 classnames 做一些很酷的事情,例如启用基于 bool 标志的 class 等

例如

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

在上面的示例中,"active" class 将仅在 props.active 为真时应用。

您还可以使用导入的样式表中的 class,使用 ES6 计算的 属性 名称。例如:

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

如您所见,这会为您的组件打开大量自定义选项。