Reputation: 33
My JSX files are full of:
<div className="...">...</div>
For example:
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>
);
This code looks wired because of this. "className" is too long for a repeatedly used attribute. Is there any common practice to get rid of this annoying repeats? Or to make it shorter?
I can make a custom component like this:
<Div cl="...">...</Div>
But I am interested if there is a common practice for this. Perhaps there is already an alias for the className attributes? Or some other way to set a CSS class name.
UPDATE
Thanks, Przemysław Zalewski for an interesting idea. But actually I am using CSS modules. So my code is:
import S from "./_.scss";
...
<div className={S.Page}>...</div>
And it does not work:
<Styled {S.Page}>...</Styled>
Upvotes: 0
Views: 1049
Reputation: 62793
You could write a Babel plugin for it - e.g. babel-plugin-react-html-attrs allows you to use class
and for
attributes when working with JSX in React and changes them to the className
and htmlFor
properties (JSX attributes are syntax sugar for object literals) React requires when JSX is being transpiled.
Here's the full source for a Babel 6 plugin which would change cl
attributes to className
when transpiling:
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]
}
}
}
}
}
My actual suggestion is just stick with className
and you'll get used to it :)
Upvotes: 1
Reputation: 3986
You should consider using a simple Styled
component for that case that handles all true boolean properties as class names and joins them as a string using 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>
);
There is 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 as full names are preserved.
Upvotes: 0
Reputation: 457
You can do it like this:
class Div extends React.Component {
render() {
return (
<div className={this.props.cl} >
{this.props.children}
</div>
);
}
};
export default Div;
And use
<Div cl="my_class"></Div>
Upvotes: 1