web-dev-qa-db-fra.com

Réagir Js en appliquant conditionnellement les attributs de classe

Je souhaite afficher et masquer de manière conditionnelle ce groupe de boutons en fonction de ce qui est transmis depuis le composant parent qui ressemble à ceci:

<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>
    );
  }
});

Cependant, rien ne se passe avec {this.props.showBulkActions? 'show': 'hidden'}. Est-ce que je fais quelque chose de mal ici?

205
apexdodge

Les accolades sont à l'intérieur de la chaîne, elle est donc évaluée en tant que chaîne. Ils doivent être à l'extérieur, cela devrait donc fonctionner:

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

Notez l'espace après "tirez à droite". Vous ne voulez pas fournir accidentellement à la classe "pull-rightshow" au lieu de "pull-right show". Les parenthèses doivent également être présentes.

395
spitfire109

Comme d'autres l'ont commenté, classnames utility est l'approche actuellement recommandée pour gérer les noms de classe CSS conditionnels dans ReactJs.

Dans votre cas, la solution ressemblera à:

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

...

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

En guise de remarque, je vous suggère d'essayer d'éviter d'utiliser les deux classes show et hidden afin que le code soit plus simple. Très probablement, vous n'avez pas besoin de définir une classe pour que quelque chose soit montré par défaut.

62
Diego V

Si vous utilisez un transpiler (tel que Babel ou Traceur), vous pouvez utiliser les nouvelles chaînes " template" ES6 ".

Voici la réponse de @ spitfire109, modifiée en conséquence:

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

Cette approche vous permet de faire des choses ordonnées comme celle-ci, en rendant soit s-is-shown, soit s-is-hidden:

<div className={`s-${this.props.showBulkActions ? 'is-shown' : 'is-hidden'}`}>
48
Bertrand

Vous pouvez utiliser ici des littéraux de chaîne

const Angle = ({show}) => {

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

   return <i className={angle} />
}
7
Musa

Ou utilisez npm classnames . C'est très facile et utile surtout pour construire la liste de classes

6
Pencilcheck

Dépendant de la réponse précise de @ spitfire109, on pourrait faire quelque chose comme ceci:

rootClassNames() {
  let names = ['my-default-class'];
  if (this.props.disabled) names.Push('text-muted', 'other-class');

  return names.join(' ');
}

puis dans la fonction de rendu:

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

garde le jsx court

6
flaky

Vous pouvez utiliser des tableaux ES6 au lieu des noms de classe . La réponse est basée sur l'article du Dr. Axel Rauschmayer: Ajout conditionnel d'entrées à l'intérieur de tableaux et d'objets .

<div className={[
                 "classAlwaysPresent", 
                 ...Array.from(condition && ["classIfTrue"])
                ].join(" ")} />
3
Tudor Morar

Au cas où vous n’auriez besoin que d’un seul nom de classe facultatif:

<div className={"btn-group pull-right " + (this.props.showBulkActions && 'show')}>
2
chibis0v

vous pouvez utiliser ceci:

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

Solution plus élégante, meilleure pour la maintenance et la lisibilité:

const classNames = ['js-btn-connect'];

if (isSelected) { classNames.Push('is-selected'); }

<Element className={classNames.join(' ')}/>
1
Nate Ben

Cela fonctionnerait pour vous

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

let _myClasses = `btn-group pull-right {this.props.showBulkActions?'show':'hidden'}`;

return (
            ...
            <div className={_myClasses}>
               ...
            </div>
    );
  }
});

0
Mano

Je voudrais ajouter que vous pouvez également utiliser un contenu variable dans le cadre de la classe

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

Le contexte est une conversation entre un bot et un utilisateur, et les styles changent en fonction de l'expéditeur, voici le résultat du navigateur:

<img src="http://imageurl" alt="Avatar" class="img-bot">
0
J C

Vous pouvez utiliser le paquet this npm. Il gère tout et propose des options pour les classes statiques et dynamiques basées sur une variable ou une fonction.

// 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
Tushar Sharma

En fonction de la valeur de this.props.showBulkActions, vous pouvez changer de classe de manière dynamique comme suit.

<div ...{...this.props.showBulkActions 
? { className: 'btn-group pull-right show' } 
: { className: 'btn-group pull-right hidden' }}>
0

2019:

React est le lac beaucoup de services publics. Mais vous n’avez pas besoin d’un paquet npm pour cela. créez simplement quelque part la fonction classnames et appelez-la quand vous en aurez besoin;

function classnames(obj){
  return Object.entries(obj).filter( p => p[1] ).map( p=>p[0] ).join(' ');
}

exemple

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