如何摆脱JSX中的“className”属性?

时间:2017-06-02 08:41:29

标签: reactjs react-jsx 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类名的方法。

更新

谢谢,PrzemysławZalewski提出了一个有趣的想法。但实际上我正在使用CSS模块。所以我的代码是:

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

它不起作用:

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

3 个答案:

答案 0 :(得分:1)

你可以这样做:

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

并使用

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

答案 1 :(得分:1)

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

以下是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并且您已经习惯了它:)

答案 2 :(得分:0)

您应该考虑对该案例使用简单的Styled组件,将所有真正的布尔属性作为类名处理,并使用classnames将它们作为字符串连接。

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

使用Proxy对象a slight variation of the idea。但是,它会在旧的JS引擎上中断,因为它无法完全填充,但允许在不事先声明MainColumn的情况下编写<styled.MainColumn full-width red>,并且使用React Developer Tools更容易调试,因为保留了全名。