score:753

Accepted answer

The curly braces are inside the string, so it is being evaluated as string. They need to be outside, so this should work:

<div className={"btn-group pull-right " + (this.props.showBulkActions ? 'show' : 'hidden')}>

Note the space after "pull-right". You don't want to accidentally provide the class "pull-rightshow" instead of "pull-right show". Also the parentheses needs to be there.

score:-1

A function to return the correct class based on a param (if present)

  getClass(param){
    let podClass = 'classA'
    switch(param.toLowerCase()){
        case 'B':
            podClass  = 'classB'
            break;
        case 'C':
            podClass  = 'classC'
            break;
    }
    return podClass
}

Now just invoke this function from the div where the corresponding class is to be applied.

 <div className={anyOtherClass + this.getClass(param)}

I successfully used this logic to apply the correct color to my bootstrap table rows.

score:0

You can use this npm package. It handles everything and has options for static and dynamic classes based on a variable or a function.

// Support for string arguments
getClassNames('class1', 'class2');

// support for Object
getClassNames({class1: true, class2 : false});

// support for all type of data
getClassNames('class1', 'class2', null, undefined, 3, ['class3', 'class4'], { 
    class5 : function() { return false; },
    class6 : function() { return true; }
});

<div className={getClassNames('show', {class1: true, class2 : false})} /> // "show class1"

score:0

Based on the value of this.props.showBulkActions you can switch classes dynamically as follows.

<div ...{...this.props.showBulkActions 
? { className: 'btn-group pull-right show' } 
: { className: 'btn-group pull-right hidden' }}>

score:0

I would like to add that you can also use a variable content as a part of the class

<img src={src} alt="Avatar" className={"img-" + messages[key].sender} />

The context is a chat between a bot and a user, and the styles change depending of the sender, this is the browser result:

<img src="http://imageurl" alt="Avatar" class="img-bot">

score:0

<div className={"h-3 w-3 rounded-full my-auto " + (index.endDate ==="present"? "bg-green-500":"bg-red-500")}></div>

Don't Forget to add an extra space after the static class names.

score:1

This would work for you

var TopicNav = React.createClass({
render: function() {

let _myClasses = `btn-group pull-right {this.props.showBulkActions?'show':'hidden'}`;

return (
            ...
            <div className={_myClasses}>
               ...
            </div>
    );
  }
});

score:1

Reference to @split fire answer, we can update it with template literals, which is more readable,For reference Checkout javascript template literal

<div className={`btn-group pull-right ${this.props.showBulkActions ? 'show' : 'hidden'}`}>

score:1

simply use this approach--

<div className={`${this.props.showActions ? 'shown' : 'hidden'}`}>

this is much more neat and clean.

score:2

This is useful when you have more than one class to append. You can join all classes in array with a space.

const visibility = this.props.showBulkActions ? "show" : ""
<div className={["btn-group pull-right", visibility].join(' ')}>

score:2

<div className={['foo', condition && 'bar'].filter(Boolean).join(' ')} />

.filter(Boolean) removes "falsey" values from the array. Since class names must be strings, anything other than that would not be included in the new filtered array.

console.log(  ['foo', true  && 'bar'].filter(Boolean).join(' ')  )
console.log(  ['foo', false && 'bar'].filter(Boolean).join(' ')  )

Above written as a function:

const cx = (...list) => list.filter(Boolean).join(' ')

// usage:
<div className={cx('foo', condition && 'bar')} />

var cx = (...list) => list.filter(Boolean).join(' ')
console.log(  cx('foo', 1 && 'bar', 1 && 'baz')  )
console.log(  cx('foo', 0 && 'bar', 1 && 'baz')  )
console.log(  cx('foo', 0 && 'bar', 0 && 'baz')  )

score:3

you can use this:

<div className={"btn-group pull-right" + (this.props.showBulkActions ? ' show' : ' hidden')}>

score:7

More elegant solution, which is better for maintenance and readability:

const classNames = ['js-btn-connect'];

if (isSelected) { classNames.push('is-selected'); }

<Element className={classNames.join(' ')}/>

score:8

2019:

React is lake a lot of utilities. But you don't need any npm package for that. just create somewhere the function classnames and call it when you need it;

function classnames(obj){
  return Object.entries(obj).filter( e => e[1] ).map( e=>e[0] ).join(' ');
}

or

function classnames(obj){
 return Object.entries(obj).map( ([cls,enb]) => enb? cls: '' ).join(' ');
}

example

  stateClass= {
    foo:true,
    bar:false,
    pony:2
  }
  classnames(stateClass) // return 'foo pony'


 <div className="foo bar {classnames(stateClass)}"> some content </div>

Just For Inspiration

declaring helper DOM element and using it native toggle method:

(DOMToken‚ÄčList)classList.toggle(class,condition)

example:

const classes = document.createElement('span').classList; 

function classstate(obj){
  for( let n in obj) classes.toggle(n,obj[n]);
 return classes; 
}
 

score:10

You can use ES6 arrays instead of classnames. The answer is based on Dr. Axel Rauschmayer article: Conditionally adding entries inside Array and object literals.

<div className={[
                 "classAlwaysPresent", 
                 ...Array.from(condition && ["classIfTrue"])
                ].join(" ")} />

score:11

Replace:

<div className="btn-group pull-right {this.props.showBulkActions ? 'show' : 'hidden'}">`

with:

<div className={`btn-group pull-right ${this.props.showBulkActions ? 'show' : 'hidden'}`}

score:12

Expending on @spitfire109's fine answer, one could do something like this:

rootClassNames() {
  let names = ['my-default-class'];
  if (this.props.disabled) names.push('text-muted', 'other-class');

  return names.join(' ');
}

and then within the render function:

<div className={this.rootClassNames()}></div>

keeps the jsx short

score:12

Or use npm classnames. It is very easy and useful especially for constructing the list of classes

score:14

In case you will need only one optional class name:

<div className={"btn-group pull-right " + (this.props.showBulkActions ? "show" : "")}>

score:18

you can simply do the following for example.

let classNameDependsOnCondtion = i18n.language == 'en' ? "classname" : "";

className={`flex flex-col lg:flex-row list-none ${classNameDependsOnCondtion }`}

OR

className={`flex flex-col lg:flex-row list-none ${i18n.language == 'en' ? "classname" : ""}`}

score:20

You can use here String literals

const Angle = ({show}) => {

   const angle = `fa ${show ? 'fa-angle-down' : 'fa-angle-right'}`;

   return <i className={angle} />
}

score:93

If you are using a transpiler (such as Babel or Traceur) you can use the new ES6 "template strings".

Here is the answer of @spitfire109, modified accordingly:

<div className={`btn-group pull-right ${this.props.showBulkActions ? 'shown' : 'hidden'}`}>

This approach allows you to do neat things like that, rendering either s-is-shown or s-is-hidden:

<div className={`s-${this.props.showBulkActions ? 'is-shown' : 'is-hidden'}`}>

score:118

As others have commented, classnames utility is the currently recommended approach to handle conditional CSS class names in ReactJs.

In your case, the solution will look like:

var btnGroupClasses = classNames(
  'btn-group',
  'pull-right',
  {
    'show': this.props.showBulkActions,
    'hidden': !this.props.showBulkActions
  }
);

...

<div className={btnGroupClasses}>...</div>

As a side note, I would suggest you to try to avoid using both show and hidden classes, so the code could be simpler. Most likely, you don't need to set a class for something to be shown by default.

2021 addendum: for performance improvement, you can look into clsx as an alternative.


Related Query

More Query from same tag