admin管理员组文章数量:1125467
I am new to ReactJS and JSX and I am having a little problem with the code below.
I am trying to add multiple classes to the className
attribute on each li
:
<li key={index} className={activeClass, data.class, "main-class"}></li>
My React component is:
var AccountMainMenu = React.createClass({
getInitialState: function() {
return { focused: 0 };
},
clicked: function(index) {
this.setState({ focused: index });
},
render: function() {
var self = this;
var accountMenuData = [
{
name: "My Account",
icon: "icon-account"
},
{
name: "Messages",
icon: "icon-message"
},
{
name: "Settings",
icon: "icon-settings"
}
/*{
name:"Help & Support <span class='font-awesome icon-support'></span>(888) 664.6261",
listClass:"no-mobile last help-support last"
}*/
];
return (
<div className="acc-header-wrapper clearfix">
<ul className="acc-btns-container">
{accountMenuData.map(function(data, index) {
var activeClass = "";
if (self.state.focused == index) {
activeClass = "active";
}
return (
<li
key={index}
className={activeClass}
onClick={self.clicked.bind(self, index)}
>
<a href="#" className={data.icon}>
{data.name}
</a>
</li>
);
})}
</ul>
</div>
);
}
});
ReactDOM.render(<AccountMainMenu />, document.getElementById("app-container"));
I am new to ReactJS and JSX and I am having a little problem with the code below.
I am trying to add multiple classes to the className
attribute on each li
:
<li key={index} className={activeClass, data.class, "main-class"}></li>
My React component is:
var AccountMainMenu = React.createClass({
getInitialState: function() {
return { focused: 0 };
},
clicked: function(index) {
this.setState({ focused: index });
},
render: function() {
var self = this;
var accountMenuData = [
{
name: "My Account",
icon: "icon-account"
},
{
name: "Messages",
icon: "icon-message"
},
{
name: "Settings",
icon: "icon-settings"
}
/*{
name:"Help & Support <span class='font-awesome icon-support'></span>(888) 664.6261",
listClass:"no-mobile last help-support last"
}*/
];
return (
<div className="acc-header-wrapper clearfix">
<ul className="acc-btns-container">
{accountMenuData.map(function(data, index) {
var activeClass = "";
if (self.state.focused == index) {
activeClass = "active";
}
return (
<li
key={index}
className={activeClass}
onClick={self.clicked.bind(self, index)}
>
<a href="#" className={data.icon}>
{data.name}
</a>
</li>
);
})}
</ul>
</div>
);
}
});
ReactDOM.render(<AccountMainMenu />, document.getElementById("app-container"));
Share
Improve this question
edited Jun 21, 2020 at 18:16
simhumileco
34.4k17 gold badges147 silver badges123 bronze badges
asked Dec 30, 2015 at 1:44
HectorHector
7,0153 gold badges17 silver badges19 bronze badges
6
|
Show 1 more comment
40 Answers
Reset to default 1 2 Next 663I use ES6
template literals. For example:
const error = this.state.valid ? '' : 'error'
const classes = `form-control round-lg ${error}`
And then just render it:
<input className={classes} />
One-liner version:
<input className={`form-control round-lg ${this.state.valid ? '' : 'error'}`} />
I use classnames when there is a fair amount of logic required for deciding the classes to (not) use. An overly simple example:
...
var liClasses = classNames({
'main-class': true,
'activeClass': self.state.focused === index
});
return (<li className={liClasses}>{data.name}</li>);
...
That said, if you don't want to include a dependency then there are better answers below.
Just use JavaScript.
<li className={[activeClass, data.klass, "main-class"].join(' ')} />
If you want to add classes based keys and values in an object you can use the following:
function classNames(classes) {
return Object.entries(classes)
.filter(([key, value]) => value)
.map(([key, value]) => key)
.join(' ');
}
const classes = {
'maybeClass': true,
'otherClass': true,
'probablyNotClass': false,
};
const myClassNames = classNames(classes);
// Output: "maybeClass otherClass"
<li className={myClassNames} />
Or even simpler:
const isEnabled = true;
const isChecked = false;
<li className={[isEnabled && 'enabled', isChecked && 'checked']
.filter(e => !!e)
.join(' ')
} />
// Output:
// <li className={'enabled'} />
Concat
No need to be fancy I am using CSS modules and it's easy
import style from '/css/style.css';
<div className={style.style1+ ' ' + style.style2} />
This will result in:
<div class="src-client-css-pages-style1-selectionItem src-client-css-pages-style2">
In other words, both styles
Conditionals
It would be easy to use the same idea with if's
const class1 = doIHaveSomething ? style.style1 : 'backupClass';
<div className={class1 + ' ' + style.style2} />
ES6
For the last year or so I have been using the template literals, so I feel its worth mentioning, i find it very expressive and easy to read:
`${class1} anotherClass ${class1}`
This can be achieved with ES6 template literals:
<input className={`base-input-class ${class1} ${class2}`}>
(edited for clarity)
You can create an element with multiple class names like this:
<li className="class1 class2 class3">foo</li>
Naturally, you can use a string containing the class names and manipulate this string to update the class names of the element.
var myClassNammes = 'class1 class2 class3';
...
<li className={myClassNames}>foo</li>
Generally people do like
<div className={ `head ${style.class1} ${Style.class2}` }><div>
OR
<div className={ 'head ' + style.class1 + ' ' + Style.class2 }><div>
OR
<div className={ ['head', style.class1 , Style.class2].join(' ') }><div>
But you can choose to Create a function to do this job
function joinAll(...classes) {
return classes.join(" ")
}
then call it like:-
<div className={joinAll('head', style.class1 , style.class2)}><div>
This is how you can do that with ES6:
className = {`
text-right
${itemId === activeItemId ? 'active' : ''}
${anotherProperty === true ? 'class1' : 'class2'}
`}
You can list multiple classes and conditions and also you can include static classes. It is not necessary to add an additional library.
Good luck ;)
Vanilla JS
No need for external libraries - just use ES6 template strings:
<i className={`${styles['foo-bar-baz']} fa fa-user fa-2x`}/>
I don't think we need to use an external package for just adding multiple classes.
I personally use
<li className={`li active`}>Stacy</li>
or
<li className={`li ${this.state.isActive ? 'active' : ''}`}>Stacy<li>
or
<li className={'li ' + (this.state.isActive ? 'active' : '') }>Stacy<li>
the second and third one in case you need to add or remove classes conditionally.
Using CSS Modules (or Sass Modules) you can isolate your styling to a specific component too.
"Component-scoped CSS allows you to write traditional, portable CSS with minimal side effects: gone are the worries of selector name collisions or affecting other components’ styles."
import * as styles from "./whatever.module.css" // css version
import * as styles from "./whatever.module.scss" // sass version
<div className={`${styles.class1} ${styles.class2}`}>
INSERT YOUR CODE HERE
</div>
Ref1 Ref2
Maybe classnames can help you.
var classNames = require('classnames');
classNames('foo', {'xx-test': true, bar: false}, {'ox-test': false}); // => 'foo xx-test'
It can be done with https://www.npmjs.com/package/clsx :
https://www.npmjs.com/package/clsx
First install it:
npm install --save clsx
Then import it in your component file:
import clsx from 'clsx';
Then use the imported function in your component:
<div className={ clsx(classes.class1, classes.class2)}>
You could do the following:
<li key={index} className={`${activeClass} ${data.class} main-class`}></li>
A short and simple solution, hope this helps.
Just adding, we can filter out empty strings.
className={[
'read-more-box',
this.props.className,
this.state.isExpanded ? 'open' : 'close',
].filter(x => !!x).join(' ')}
You can create an element with multiple class names like this, I tryed these both way, its working fine...
If you importing any css then you can follow this way : Way 1:
import React, { Component, PropTypes } from 'react';
import csjs from 'csjs';
import styles from './styles';
import insertCss from 'insert-css';
import classNames from 'classnames';
insertCss(csjs.getCss(styles));
export default class Foo extends Component {
render() {
return (
<div className={[styles.class1, styles.class2].join(' ')}>
{ 'text' }
</div>
);
}
}
way 2:
import React, { Component, PropTypes } from 'react';
import csjs from 'csjs';
import styles from './styles';
import insertCss from 'insert-css';
import classNames from 'classnames';
insertCss(csjs.getCss(styles));
export default class Foo extends Component {
render() {
return (
<div className={styles.class1 + ' ' + styles.class2}>
{ 'text' }
</div>
);
}
}
**
If you applying css as internal :
const myStyle = {
color: "#fff"
};
// React Element using Jsx
const myReactElement = (
<h1 style={myStyle} className="myClassName myClassName1">
Hello World!
</h1>
);
ReactDOM.render(myReactElement, document.getElementById("app"));
.myClassName {
background-color: #333;
padding: 10px;
}
.myClassName1{
border: 2px solid #000;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.4.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.4.0/umd/react-dom.production.min.js"></script>
<div id="app">
</div>
This seem to work for me
<Link className={[classes.button, classes.buttonFirst]}>
for more classes adding
... className={`${classes.hello} ${classes.hello1}`...
I know this is a late answer, but I hope this will help someone.
Consider that you have defined following classes in a css file 'primary', 'font-i', 'font-xl'
- The first step would be to import the CSS file.
- Then
<h3 class = {` ${'primary'} ${'font-i'} font-xl`}> HELLO WORLD </h3>
would do the trick!
For more info: https://www.youtube.com/watch?v=j5P9FHiBVNo&list=PLC3y8-rFHvwgg3vaYJgHGnModB54rxOk3&index=20
Create a function like this
function cssClass(...c) {
return c.join(" ")
}
Call it when needed.
<div className={cssClass("head",Style.element,"black")}><div>
Late to the party, but why use third party for such a simple problem?
You could either do it as @Huw Davies mentioned - the best way
1. <i className={`${styles['foo-bar-baz']} fa fa-user fa-2x`}/>
2. <i className={[styles['foo-bar-baz'], 'fa fa-user', 'fa-2x'].join(' ')}
Both are good. But writing can become complex for a large app. To make it optimal, I do the same above things but put it in a helper class
Using my below helper function, allows me to keep the logic separate for future editing, and also gives me multiple ways to add the classes
classNames(styles['foo-bar-baz], 'fa fa-user', 'fa-2x')
or
classNames([styles['foo-bar-baz], 'fa fa-user', 'fa-2x'])
This is my helper function below. I've put it in a helper.js where I keep all my common methods. Being such a simple function, I avoided using 3rd party to keep control
export function classNames (classes) {
if(classes && classes.constructor === Array) {
return classes.join(' ')
} else if(arguments[0] !== undefined) {
return [...arguments].join(' ')
}
return ''
}
You can use arrays and then join them using space.
<li key={index} className={[activeClass, data.class, "main-class"].join(' ')}></li>
This will result in :
<li key={index} class="activeClass data.class main-class"></li>
clsx makes this simple!
"The clsx function can take any number of arguments, each of which can be an Object, Array, Boolean, or String."
-- clsx docs on npmjs.com
Import it:
import clsx from 'clsx'
Use it:
<li key={index} className={clsx(activeClass, data.class, "main-class")}></li>
For this issue I use this util function:
export function cn(...args: string[]): string{
return args.filter(Boolean).join(' ');
}
and apply it in this way:
<div className={cn(inter.className, styles.planColumns)}>
When I have many varying classes, I have found the following to be useful.
The filter removes any of the null
values and the join puts all the remaining values into a space separated string.
const buttonClasses = [
"Button",
disabled ? "disabled" : null,
active ? "active" : null
].filter((class) => class).join(" ")
<button className={buttonClasses} onClick={onClick} disabled={disabled ? disabled : false}>
I used this syntax
<div
className={[
"d-inline-flex justify-content-center align-items-center ",
withWrapper && `ft-icon-wrapper ft-icon-wrapper-${size}`,
wrapperClass,
].join(" ")}
>
<img
className={`ft-icon ft-icon-${size} ${iconClass}`}
alt={id}
src={icon}
/>
</div>
Using facebook's TodoTextInput.js example
render() {
return (
<input className={
classnames({
edit: this.props.editing,
'new-todo': this.props.newTodo
})}
type="text"
placeholder={this.props.placeholder}
autoFocus="true"
value={this.state.text}
onBlur={this.handleBlur}
onChange={this.handleChange}
onKeyDown={this.handleSubmit} />
)
}
replacing classnames with plain vanilla js code will look like this:
render() {
return (
<input
className={`
${this.props.editing ? 'edit' : ''} ${this.props.newTodo ? 'new-todo' : ''}
`}
type="text"
placeholder={this.props.placeholder}
autoFocus="true"
value={this.state.text}
onBlur={this.handleBlur}
onChange={this.handleChange}
onKeyDown={this.handleSubmit} />
)
}
If you don't feel like importing another module, this function works like the classNames
module.
function classNames(rules) {
var classes = ''
Object.keys(rules).forEach(item => {
if (rules[item])
classes += (classes.length ? ' ' : '') + item
})
return classes
}
You can use it like this:
render() {
var classes = classNames({
'storeInfoDiv': true,
'hover': this.state.isHovered == this.props.store.store_id
})
return (
<SomeComponent style={classes} />
)
}
Use https://www.npmjs.com/package/classnames
import classNames from 'classnames';
Can use multiple classes using comas seperated:
<li className={classNames(classes.tableCellLabel, classes.tableCell)}>Total</li>
Can use multiple classes using comas separated with condition:
<li className={classNames(classes.buttonArea, !nodes.length && classes.buttonAreaHidden)}>Hello World</li>
Using array as props to classNames will also work, but gives warning e.g.
className={[classes.tableCellLabel, classes.tableCell]}
You can use react-directive, it supports all react elements and it even supports directives such as dirIf
, dirShow
, dirFor
and extended className
You can do something like below:
import { useState } from 'react'
import directive from 'react-directive';
function Component() {
const [isActive, setIsActive] = useState(true);
const [isDisabled, setIsDisabled] = useState(false);
return <directive.div className={{isActive, isDisabled}}>Contents</directive.div>;
}
// Renders <div class="isActive">Contents</div>
You can even supply some dependencies that will re-calculate the class names when any changes occurs. I am the author of the library.
本文标签: javascriptHow to add multiple classes to a ReactJS ComponentStack Overflow
版权声明:本文标题:javascript - How to add multiple classes to a ReactJS Component? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736667946a1946764.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
classNames={{foo: true, bar: true, baz: false}}
andclassNames={["foo", "bar"]}
just work? – Peter V. Mørch Commented Mar 2, 2020 at 9:57<div className={classes(isTrue && "willRenderThisClass")} />
– Ivan Hanák Commented Jul 7, 2020 at 19:47