React Js conditionally applying class attributes

414,100

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.

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.

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

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" : ""}`}
Share:
414,100
apexdodge
Author by

apexdodge

General Manager at OpenWater (http://www.getopenwater.com) Follow me on Twitter

Updated on July 12, 2022

Comments

  • apexdodge
    apexdodge almost 2 years

    I want to conditionally show and hide this button group depending on what is passed in 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>
        );
      }
    });
    

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

  • apexdodge
    apexdodge almost 9 years
    Thanks! I had to modify it slightly because for some reason it wasn't outputting btn-group pull-right at all. Just show or hidden.
  • Dave Cooper
    Dave Cooper over 7 years
    This is particularly helpful in certain cases where classnames might not be appropriate. If you are in your render function and you have a map, you might only know whether you want to add a class at the time you are rendering it, so this answer is quite useful for that.
  • Alexander Nied
    Alexander Nied about 7 years
    Could you elaborate on classNames utility being the "currently recommended approach"? Is that captured in some well-regarded best practices document somewhere? Or just sort of the word of mouth around React and classNames at the moment?
  • Diego V
    Diego V about 7 years
    @anied At the time of writing it was recommended in official React documentation: web.archive.org/web/20160602124910/http://facebook.github.io‌​:80/…
  • devonj
    devonj almost 7 years
    great alternative instead of having a bunch of conditional templates in your render or return
  • mibbit
    mibbit over 6 years
    please expand upon this, what is condition?
  • Tudor Morar
    Tudor Morar over 6 years
    const condition = (1 === 1);
  • mark
    mark about 6 years
    Be careful with the second approach, especially in large codebases, as it makes the class strings less greppable. For example, if someone searches for s-is-shown or s-is-hidden in the codebase, they won't find this code.
  • RamY
    RamY almost 6 years
    @apexdodge what modification you had to do. I have the same issue.
  • Franklin Yu
    Franklin Yu over 5 years
    It is still mentioned in latest documentation: "If you often find yourself writing code like this, classnames package can simplify it."
  • Ian
    Ian over 5 years
    @RamY One way is to put all the classes inside the conditional this.props.showBulkActions ? 'btn-group pull-right show' : 'btn-group pull-right hidden'). Not elegant but it works.
  • RA.
    RA. over 4 years
    This will append false class when condition fails.
  • Kalamarico
    Kalamarico almost 3 years
    instead of "" in the ternary use null, if not, the class property is set in the element, with null not, it's better
  • Kevin Law
    Kevin Law over 2 years
    As of 2021, instead of classnames you might want to try clsx
  • Anthony Avila
    Anthony Avila about 2 years
    If you are conditionally rendering a single className inline and don't want a class to appear for one of the conditions, you can return null or undefined instead of an empty string. Example: className={condition ? 'red' : null} or className={condition ? 'red' : undefined} It's better to keep your markup clean rather than having elements appear like <div class> or `<div class="null">
  • Hasan Zahran
    Hasan Zahran about 2 years
    @AnthonyAvila true, also its better to use classnames npmjs.com/package/classnames to avoid printing extra empty spaces.
  • allenhwkim
    allenhwkim about 2 years
    the way react handle this is so out of convention.
  • PeeJee
    PeeJee about 2 years
    Cleanest approach imo. Thanks!