ReactJS ajoute une classe dynamique aux noms de classe manuels

158

J'ai besoin d'ajouter une classe dynamique à une liste de classes régulières, mais je n'ai aucune idée de comment (j'utilise babel), quelque chose comme ceci:

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

Des idées?

L'humanité1023
la source
Réponses utiles pour les meilleures pratiques de style reactjs sur lien
Rahil Ahmad

Réponses:

241

Vous pouvez soit faire ceci, JavaScript normal:

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

ou la version du modèle de chaîne, avec des backticks:

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

Les deux types sont bien sûr juste du JavaScript, mais le premier modèle est le type traditionnel.

Quoi qu'il en soit, dans JSX, tout ce qui est entre accolades est exécuté en JavaScript, vous pouvez donc faire ce que vous voulez. Mais combiner des chaînes JSX et des accolades n'est pas une option pour les attributs.

dannyjolie
la source
et que faire en cas de classes multiples?
Pardeep Jain
5
Dans le cas de plusieurs classes dynamiques, toutes les classes dynamiques doivent provenir de l'état, c'est-à-dire qu'il n'est pas possible d'utiliser element.classList.add("my-class"); permettant donc:className={`wrapper searchDiv ${this.state.something ? "my-class " : ""} ${this.state.somethingElse ? "my-other-class " : ""}`}
Kevin Farrugia
className={'wrapper searchDiv} + this.state.isTrue ? 'my-class' : ' 'Cela ne marche pas. Quelqu'un peut-il dire pourquoi?
kryptokinght
54

En fonction du nombre de classes dynamiques que vous devez ajouter au fur et à mesure de la croissance de votre projet, il vaut probablement la peine de consulter l' utilitaire de noms de classe de JedWatson sur GitHub. Il vous permet de représenter vos classes conditionnelles en tant qu'objet et renvoie celles dont la valeur est vraie.

Donc, à titre d'exemple tiré de sa documentation React:

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

} 

Étant donné que React déclenche un nouveau rendu en cas de changement d'état, vos noms de classes dynamiques sont gérés naturellement et tenus à jour avec l'état de votre composant.

Brad Colthurst
la source
5
L'utilisation de classNames pour une chose aussi simple est une exagération. Évitez de l'utiliser et optez pour la réponse simple de dannyjolie
checklist
2
Êtes-vous sûr que c'est une chose simple? Presque toujours, vous voulez avoir un contrôle total fin sur les classes appliquées aux éléments.
Dragas
5
@checklist Je dirais le contraire, le package des noms de classes fait 1,1 Ko avant Gzipping (et un demi-Ko après Gzipping), n'a pas de dépendances et fournit une API beaucoup plus propre pour la manipulation des noms de classes. Il n'est pas nécessaire d'optimiser prématurément quelque chose d'aussi petit, lorsque l'API est beaucoup plus expressive. Lorsque vous utilisez la manipulation de chaînes standard, vous devez vous rappeler de tenir compte de l'espacement, soit avant chaque nom de classe conditionnel, soit après chaque nom de classe standard.
tomhughes
classNames est génial, j'ai trouvé que la lecture, l'ajout et la correction d'accessoires étaient plus faciles que la manipulation manuelle car le composant devenait de plus en plus complexe.
MiFiHiBye
37

Une syntaxe simple possible sera:

<div className={`wrapper searchDiv ${this.state.something}`}>
oligopol
la source
26

Voici la meilleure option pour Dynamic className, faites simplement une concaténation comme nous le faisons en Javascript.

     className={
        "badge " +
        (this.state.value ? "badge-primary " : "badge-danger ") +
        " m-4"
      }
Saad Mirza
la source
C'est la meilleure solution sans aucun problème de peluchage. A travaillé comme un charme. Je vous remercie.
Royal.O
3

Si vous avez besoin de noms de style qui doivent apparaître selon la condition d'état, je préfère utiliser cette construction:

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

essayez ceci en utilisant des crochets:

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

et ajoutez ceci dans l'attribut className:

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

pour ajouter une classe:

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

pour supprimer la classe:

        const deleteClass= classToDelete => {

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

        }
Hamza Khattabi
la source
1

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

<div className={getClassNames({class1: true, class2 : false})} />
Tushar Sharma
la source
1
getBadgeClasses() {
    let classes = "badge m-2 ";
    classes += (this.state.count === 0) ? "badge-warning" : "badge-primary";
    return classes;
}

<span className={this.getBadgeClasses()}>Total Count</span>
Harshvardhan Singh Baghel
la source
-1
className={css(styles.mainDiv, 'subContainer')}

Cette solution a fait ses preuves dans React SPFx.

Ajoutez également une instruction d'importation:

import { css } from 'office-ui-fabric-react/lib/Utilities';
Harjot Singh
la source