React Js conditionally applying class attributes

React Js conditionally applying class attributes

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

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

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

);
}
});

Nothing is happening however, with the {this.props.showBulkActions ? ‘show’ : ‘hidden’}. Am I doing anything wrong here?

Solutions/Answers:

Solution 1:

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.

Solution 2:

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

Related:  Drawing a path with a line in OpenLayers using JavaScript

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.

Solution 3:

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

Solution 4:

You can use here String literals

const Angle = ({show}) => {

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

   return <i className={angle} />
}

Solution 5:

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

Related:  React Native fetch() Network Request Failed

Solution 6:

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