如何摆脱 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 时使用 class
和 for
属性,并将它们更改为 className
和 htmlFor
属性(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
,你会习惯的:)
我的 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 时使用 class
和 for
属性,并将它们更改为 className
和 htmlFor
属性(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
,你会习惯的:)