如何摆脱 JSX 中的 "className" 属性?

How to get rid of the "className" attribute in JSX?

我的 JSX 文件充满了:

<div className="...">...</div>

例如:

const Page = () => (

  <div className="Page">

    <div className="sideMenu">
      <Route path="/" component={SidemenuMainCont} />
    </div>

    <div className="mainColumn">
      <div className="header">
        <Header />
      </div>
      <div className="section">
        <Route path="/" component={TenCont} />
      </div>
      <div className="footer">
        <Footer />
      </div>
    </div>

    <AuthLoginModalCont />

  </div>

);

因此,这段代码看起来很连线。 "className" 对于重复使用的属性来说太长了。有什么常见的做法可以摆脱这种烦人的重复吗?还是让它更短?

我可以制作这样的自定义组件:

<Div cl="...">...</Div>

但我很感兴趣是否有这方面的通用做法。也许 className 属性已经有了一个别名?或者通过其他方式设置 CSS class 名称。

更新

谢谢 Przemysław Zalewski 的有趣想法。但实际上我正在使用 CSS 模块。所以我的代码是:

import S from "./_.scss";
...
<div className={S.Page}>...</div>

它不起作用:

<Styled {S.Page}>...</Styled>

你可以这样做:

    class Div extends React.Component {
        render() {
            return (
                <div className={this.props.cl} >
                    {this.props.children}
                </div>
            );
        }
    };
    export default Div;

并使用

<Div cl="my_class"></Div>

对于这种情况,您应该考虑使用一个简单的 Styled 组件,它将所有真正的布尔属性作为 class 名称处理,并使用 classnames.[=17= 将它们作为字符串连接起来]

class Styled extends React.PureComponent {
    render() {
        const { children, tag: Tag = 'div', ...rest } = this.props;
        const [booleans, others] = partition(x => x === true)(rest)

        return (
            <Tag
                className={classNames(booleans)}
                {...others}
            >
                {children}
            </Tag>
        )
    }
}

const Page = () => (
  <Styled Page>

    <Styled sideMenu>
      <Route path="/" component={SidemenuMainCont} />
    </Styled>

    <Styled mainColumn>
      <Styled Header>
        <Header />
      </Styled>
      <Styled section tag="section">
        <Route path="/" component={TenCont} />
      </Styled section>
      <Styled footer tag="footer">
        <Footer />
      </Styled>
    </Styled>

    <AuthLoginModalCont />

  </Styled>
);

a slight variation of the idea with the use of Proxy object. However, it will break on older JS engines as it cannot be fully polyfilled but allows writing <styled.MainColumn full-width red> without declaring MainColumn beforehand and it is more easily debuggable with React Developer Tools 因为保留了全名。

您可以为其编写一个 Babel 插件 - 例如babel-plugin-react-html-attrs 允许您在 React 中使用 JSX 时使用 classfor 属性,并将它们更改为 classNamehtmlFor 属性(JSX 属性是语法糖对于对象字面量)React 需要在转译 JSX 时。

这是 Babel 6 插件的完整源代码,它会在转译时将 cl 属性更改为 className

var TRANSLATIONS = {
  'cl': 'className'
}

module.exports = function() {
  return {
    visitor: {
      JSXAttribute: function(node) {
        if (node.node.name.name in TRANSLATIONS) {
          node.node.name.name = TRANSLATIONS[node.node.name.name]
        }
      }
    }
  }
}

我的实际建议是坚持使用 className,你会习惯的:)