How to dynamically add a class to manual class names?

CssReactjs

Css Problem Overview


I need to add a dynamic class to a list of regular classes, but have no idea how (I'm using babel), something like this:

<div className="wrapper searchDiv {this.state.something}">
...
</div>

Any ideas?

Css Solutions


Solution 1 - Css

You can either do this, normal JavaScript:

className={'wrapper searchDiv ' + this.state.something}

or the string template version, with backticks:

className={`wrapper searchDiv ${this.state.something}`}

Both types are of course just JavaScript, but the first pattern is the traditional kind.

Anyway, in JSX, anything enclosed in curly brackets is executed as JavaScript, so you can basically do whatever you want there. But combining JSX strings and curly brackets is a no-go for attributes.

Solution 2 - Css

Depending on how many dynamic classes you need to add as your project grows it's probably worth checking out the classnames utility by JedWatson on GitHub. It allows you to represent your conditional classes as an object and returns those that evaluate to true.

So as an example from its React documentation:

render () {

var btnClass = classNames({
  'btn': true,
  'btn-pressed': this.state.isPressed,
  'btn-over': !this.state.isPressed && this.state.isHovered
});

return <button className={btnClass}>I'm a button!</button>;

} 

Since React triggers a re-render when there is a state change, your dynamic class names are handled naturally and kept up to date with the state of your component.

Solution 3 - Css

A simple possible syntax will be:

<div className={`wrapper searchDiv ${this.state.something}`}>

Solution 4 - Css

Here is the Best Option for Dynamic className , just do some concatenation like we do in Javascript.

     className={
        "badge " +
        (this.state.value ? "badge-primary " : "badge-danger ") +
        " m-4"
      }

Solution 5 - Css

Don't think of a solution so complicated.

here is the easiest solution for your problem.

<div className={`wrapper searchDiv ${this.state.something}`}>
   ...
</div>

Solution 6 - Css

try this using hooks:

const [dynamicClasses, setDynamicClasses] = React.useState([    "dynamicClass1", "dynamicClass2"]);

and add this in className attribute :

<div className=`wrapper searchDiv ${[...dynamicClasses]}`>
...
</div>

to add class :

    const addClass = newClass => {
       setDynamicClasses([...dynamicClasses, newClass])
    }

to delete class :

        const deleteClass= classToDelete => {

           setDynamicClasses(dynamicClasses.filter(class = > {
             class !== classToDelete
           }));

        }

Solution 7 - Css

If you need style names which should appear according to the state condition, I prefer to use this construction:

<div className={'wrapper searchDiv' + (this.state.something === "a" ? " anotherClass" : "")'}>

Solution 8 - Css

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', ['class3', 'class4'], { 
    class5 : function() { return false; },
    class6 : function() { return true; }
});

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

Solution 9 - Css

If you're using css modules this is what worked for me.

const [condition, setCondition] = useState(false);

\\ toggle condition

return (
  <span className={`${styles.always} ${(condition ? styles.sometimes : '')`}>
  </span>
)

Solution 10 - Css

getBadgeClasses() {
    let classes = "badge m-2 ";
    classes += (this.state.count === 0) ? "badge-warning" : "badge-primary";
    return classes;
}

<span className={this.getBadgeClasses()}>Total Count</span>

Solution 11 - Css

className={css(styles.mainDiv, 'subContainer')}

This solution is tried and tested in React SPFx.

Also add import statement :

import { css } from 'office-ui-fabric-react/lib/Utilities';

Solution 12 - Css

const ClassToggleFC= () =>{
  
  const [isClass, setClass] = useState(false);

  const toggle =() => {
       setClass( prevState => !prevState)
  }
  
  return(
      <>
        <h1 className={ isClass ? "heading" : ""}> Hiii There </h1>
       <button onClick={toggle}>Toggle</button>
      </>
   )

}

I simply created a Function Component. Inside I take a state and set initial value is false..

I have a button for toggling state..

Whenever we change state rerender component and if state value (isClass) is false h1's className should be "" and if state value (isClass) is true h1's className is "heading"

Solution 13 - Css

Even though all of the answers above are quite good, the one that caught my attention is the string interpolation solution. So I'd like to propose a different approach to that using a custom StringBuilder.

Here's the implementation.

class StringBuilder {
  static Builder() {
    class Builder {
      constructor() {
        this.bucket = [];
      }

      append(str) {
        if (str !== null) {
          this.bucket.push(str);
        }
        return this;
      }

      build() {
        return this.bucket.join(' ');
      }
    }
    return new Builder();
  }
}

Then you would just use it like this within a component.

const Field = (props) => {
  const { label } = props;

  const [hasFocus, setFocus] = useState(false);

  const labelClasses = new StringBuilder.Builder()
    .append('form-control')
    .append(hasFocus ? 'has-focus' : null)
    .build();

  const turnOnFocus = () => setFocus(true);
  const turnOffFocus = () => setFocus(false);

  return (
    <div onClick={turnOnFocus} onBlur={turnOffFocus} className="form-group">
      <input
        type="text"
        defaultValue=""
        onChange={setValue}
      />
      <label className={labelClasses}>{label}</label>
    </div>
  );
};

In general, if you have more elements that require dynamic CSS classes, you could just instantiate another builder for that particular element. Additionally, if the class appears in more than one element with the same logic, then the solution would be extracting that logic to a method or function.

Solution 14 - Css

[UPDATED Apr-21 2022: Adding curly brackets before and after backticks to prevent error]

you can simply use the condition for applying the specific class you want

<div className={`wrapper searchDiv ${this.state.something ? "class that you want" : ""}`}>

if you want to use the class of makeStyle you can use it like

<div className={`wrapper searchDiv ${this.state.something ? classes.specifiedClass : ""}`}>

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMankind1023View Question on Stackoverflow
Solution 1 - CssdannyjolieView Answer on Stackoverflow
Solution 2 - CssBrad ColthurstView Answer on Stackoverflow
Solution 3 - CssoligopolView Answer on Stackoverflow
Solution 4 - CssSaad MirzaView Answer on Stackoverflow
Solution 5 - CssDaniel PaulView Answer on Stackoverflow
Solution 6 - CssHamza KhattabiView Answer on Stackoverflow
Solution 7 - CssSergeyView Answer on Stackoverflow
Solution 8 - CssTushar SharmaView Answer on Stackoverflow
Solution 9 - CssquarterpiView Answer on Stackoverflow
Solution 10 - CssHarshvardhan Singh BaghelView Answer on Stackoverflow
Solution 11 - CssHarjot SinghView Answer on Stackoverflow
Solution 12 - Cssuser11889340View Answer on Stackoverflow
Solution 13 - CssAlvaroView Answer on Stackoverflow
Solution 14 - CssIhtisham TanveerView Answer on Stackoverflow