React Js by conditionally applying class attributes

I want to conditionally show and hide this group of buttons depending on what is passed from the parent component, which looks like this:

<TopicNav showBulkActions={this.__hasMultipleSelected} /> 

....

 __hasMultipleSelected: function() { return false; //return true or false depending on data } 

....

 var TopicNav = React.createClass({ render: function() { return ( <div className="row"> <div className="col-lg-6"> <div className="btn-group pull-right {this.props.showBulkActions ? 'show' : 'hidden'}"> <button type="button" className="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-expanded="false"> Bulk Actions <span className="caret"></span> </button> <ul className="dropdown-menu" role="menu"> <li><a href="#">Merge into New Session</a></li> <li><a href="#">Add to Existing Session</a></li> <li className="divider"></li> <li><a href="#">Delete</a></li> </ul> </div> </div> </div> ); } }); 

However, nothing happens with {this.props.showBulkActions? 'show hidden'}. Am I something wrong here?

+271
javascript css reactjs twitter-bootstrap-3
May 29 '15 at
source share
15 answers

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

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

Note the space after pull-right. You do not want to accidentally provide the "pull-rightshow" class instead of the "pull-right show". There should also be parentheses.

+492
May 29 '15 at 15:18
source share

As others have noted, the classnames utility is the currently recommended approach for handling conditional CSS class names in ReactJs.

In your case, the solution will look like this:

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

...

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

As a side note, I suggest you try to avoid using the show and hidden classes, so the code might be simpler. Most likely, you do not need to set a class to display anything by default.

+75
Mar 01 '16 at 9:08
source share

If you are using a transpiler (like Babel or Traceur), you can use the new ES6 " pattern string ".

Here is the @ spitfire109 answer, modified accordingly:

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

This approach allows you to do such neat things by providing either s-is-shown or s-is-hidden :

 <div className={`s-${this.props.showBulkActions ? 'is-shown' : 'is-hidden'}`}> 
+55
Sep 05 '16 at 13:12
source share

You can use string literals here

 const Angle = ({show}) => { const angle = 'fa ${show ? 'fa-angle-down' : 'fa-angle-right'}'; return <i className={angle} /> } 
+13
Jul 09 '18 at 8:14
source share

Spending on @ spitfire109 a great answer, you can 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 inside the render function:

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

stores jsx short

+6
May 2 '16 at 13:53
source share

Or use npm classnames . This is very easy and useful, especially for building a list of classes.

+6
Jan 27 '17 at 13:08 on
source share

You can use ES6 arrays instead of classes. The answer is based on an article by Dr. Axel Rauschmeier: Conditionally adding records inside arrays and object literals .

 <div className={[ "classAlwaysPresent", ...Array.from(condition && ["classIfTrue"]) ].join(" ")} /> 
+4
Sep 05 '17 at 8:41
source share

A more elegant solution that is better for service and readability:

 const classNames = ['js-btn-connect']; if (isSelected) { classNames.push('is-selected'); } <Element className={classNames.join(' ')}/> 
+3
Jul 27 '17 at 7:37
source share

2019:

The response to the lake is many helpful. But for this you do not need the npm package. just create somewhere the name classnames function and call it when you need to;

 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( ([k,v]) => v?k:'' ).join(' '); } 

example

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

inspirational bonus only

you can declare a helper element and take its classList to access the DOMToken List and maybe write something like that

 const classes = document.createElement('span').classList; //DOMTokenโ€‹List; function classnames(obj){ classes.value = ''; return Object.entries(obj).reduce( (c, [k,v]) => (c.toggle(k,v),c), classes ).value; } 
+3
Jan 12 '19 at 17:05
source share

You can use this:

 <div className={"btn-group pull-right" + (this.props.showBulkActions ? ' show' : ' hidden')}> 
+2
May 12 '19 at 11:56
source share

It will 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> ); } }); 
+1
Sep 28 '18 at 17:45
source share

You can use this npm package. It handles everything and has parameters for static and dynamic classes based on a variable or 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" 
0
Dec 03 '17 at 18:27
source share

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

 <div ...{...this.props.showBulkActions ? { className: 'btn-group pull-right show' } : { className: 'btn-group pull-right hidden' }}> 
0
May 9, '19 at 11:08
source share

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

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

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

 <img src="http://imageurl" alt="Avatar" class="img-bot"> 
0
May 15 '19 at
source share

You can use if the concept is

 var Count=React.createClass({ getInitialState: function() { var state={counter:1}; setInterval(function(){ this.setState( {counter:this.state.counter+(this.state.counter==1000?9999999999:1)}) }.bind(this),1); return state; }, render:function(){ return( <div> Counter<br/> {this.state.counter} </div> ) } } ) 
-7
Jun 21 '17 at 12:15
source share



All Articles