psullivan6
psullivan6

Reputation: 71

How do I add a conditional class in React without removing other classes?

I want to add a class name to an element conditionally based on the truthiness of a state object, while maintaining the classes applied via a plugin on initial render.

Example that doesn't work:

import React from 'react';
import classnames from 'classnames';

export default class CoolThing extends React.Component{
  constructor(props) {
    super(props);
  }

  componentDidMount() {
    // This plugin sets classes to the this.refs.root DOM element when it initializes 
    $(this.refs.root).jqueryPluginIHaveToUseThatSetsClassesAndDoesStuff();
  }

  handleClick = () => {
    this.setState({
      active: true
    })
  }

  render() {
    const classNames = classnames({
      active: this.state.active
    });

    return (
      <div ref="root" className={ classnames } onClick={ this.handleClick }></div>
    )
  }
}

Same as above, but with this render also fails:

render() {
  return (
    <div ref="root" className={ this.state.active ? "CoolThing active" : "CoolThing" } onClick={ this.handleClick }></div>
  )
}

The desired result would have the "CoolThing" class always on this example's div tag in addition to whatever classes the jqueryPluginIHaveToUseThatSetsClassesAndDoesStuff applied. THEN, depending upon a user action, the active class would also be applied and not overwrite any of the previously applied classes.

I would like to avoid:

Upvotes: 1

Views: 1517

Answers (2)

CXNAJ
CXNAJ

Reputation: 43

try this

render() {
  return (
    {this.state.active ? <div ref="root" className="CoolThing active" 
    onClick`enter code here`={ this.handleClick }></div>
    : <div ref="root" className="CoolThing" 
    onClick={ this.handleClick }></div> 
  )
}

Upvotes: 0

kfitzi
kfitzi

Reputation: 46

I would set the className to CoolThing by default, then check state.active in the render function. If you have other classes to add and you want them to persist, store them in the state, then just add them to the string template as well. This allows you to have CoolThing be the default class even if the state values have not been set yet.

render() {

    let jQueryClasses = this.state.jQueryClasses; 
    let active = { this.state.active ? " active": ""};
    return (
        <div ref="root" className={`CoolThing${jQueryClasses}${active}`} 
                        onClick={ this.handleClick }/>);
}

Upvotes: 1

Related Questions