How to add multiple classes to a ReactJS Component?

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 &amp; Support &nbsp; <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")); 
5

37 Answers

1 2

I 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'}`} /> 
6

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.

10

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'} /> 
5

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> 

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}` 
5

This can be achieved with ES6 template literals:

<input className={`base-input-class ${class1} ${class2}`}> 

(edited for clarity)

3

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> 
2

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

3

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.

3

Vanilla JS

No need for external libraries - just use ES6 template strings:

<i className={`${styles['foo-bar-baz']} fa fa-user fa-2x`}/> 
4

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> 

Maybe classnames can help you.

var classNames = require('classnames'); classNames('foo', {'xx-test': true, bar: false}, {'ox-test': false}); // => 'foo xx-test' 
2

You could do the following:

<li key={index} className={`${activeClass} ${data.class} main-class`}></li> 

A short and simple solution, hope this helps.

1

It can be done with :

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

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=""></script> <script src=""></script> <div> </div>
1

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:

0

This seem to work for me

<Link className={[classes.button, classes.buttonFirst]}> 
1

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}></li> 

Create a function like this

function cssClass(...c) { return c.join(" ") } 

Call it when needed.

<div className={cssClass("head",Style.element,"black")}><div> 

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

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}> 

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} /> ) } 
1

Use

import classNames from 'classnames';

  1. Can use multiple classes using comas seperated:

    <li className={classNames(classes.tableCellLabel, classes.tableCell)}>Total</li> 
  2. 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]} 
1

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> 

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> 
1

That's what I do:

Component:

const Button = ({ className }) => ( <div className={ className }> </div> ); 

Calling Component:

<Button className = 'hashButton free anotherClass' /> 

I am using React 16.6.3 and @Material UI 3.5.1, and is able to use arrays in className like className={[classes.tableCell, classes.capitalize]}

So in your example, the following would be similar.

<li key={index} className={[activeClass, data.class, "main-class"]}></li> 
1

1 2

You Might Also Like