Comment ajouter plusieurs classes dans Material UI à l'aide des accessoires de classes

92

À l'aide de la méthode css-in-js pour ajouter des classes à un composant react, comment ajouter plusieurs composants?

Voici la variable classes:

const styles = theme => ({
 container: {
  display: 'flex',
  flexWrap: 'wrap'
},
 spacious: {
  padding: 10
},
});

Voici comment je l'ai utilisé:

    return (
     <div className={ this.props.classes.container }>

Ce qui précède fonctionne, mais existe-t-il un moyen d'ajouter les deux classes sans utiliser le classNamespackage npm? Quelque chose comme:

     <div className={ this.props.classes.container + this.props.classes.spacious}>
q3e
la source
3
Peut-être que je manque quelque chose, mais ne pouvez-vous pas simplement faire <div className = "container spacieux"> Pourquoi avez-vous besoin de le passer en tant que propriété?
Leo Farmer
2
il vous manque juste un espace entre les deux classNames.
Shanimal
Ouais, comme indiqué ci-dessus, il vous suffit de concater correctement les classes avec un espace entre les deux! Pas besoin de packages supplémentaires.
Taylor A. Leach

Réponses:

180

vous pouvez utiliser l'interpolation de chaîne:

<div className={`${this.props.classes.container} ${this.props.classes.spacious}`}>
Klugjo
la source
5
et n'oubliez pas de ne pas ajouter de virgules entre les classes! Je l'ai fait par erreur et le premier s'est cassé silencieusement sans s'en apercevoir pendant un moment
Pere
Et il doit y avoir un espace entre les classes
Yoel
49

vous pouvez installer ce package

https://github.com/JedWatson/classnames

puis utilisez-le comme ça

classNames('foo', 'bar'); // => 'foo bar'
classNames('foo', { bar: true }); // => 'foo bar'
classNames({ 'foo-bar': true }); // => 'foo-bar'
classNames({ 'foo-bar': false }); // => ''
classNames({ foo: true }, { bar: true }); // => 'foo bar'
classNames({ foo: true, bar: true }); // => 'foo bar'

// lots of arguments of various types
classNames('foo', { bar: true, duck: false }, 'baz', { quux: true }); // => 'foo bar baz quux'

// other falsy values are just ignored
classNames(null, false, 'bar', undefined, 0, 1, { baz: null }, ''); // => 'bar 1'
Mini
la source
3
C'est l'approche que Material-UI utilise dans certains de leurs exemples, et fonctionne bien, je le recommande donc.
Craig Myles
2
Cela devrait être la réponse acceptée. Fonctionne comme prévu
Howie
2
J'utilise également cette approche. Utile non seulement pour avoir plusieurs noms de classe, mais aussi pour le rendre conditionnel.
mouthzipper
4
@material-ui/coredépend maintenant de clsx, donc si vous ne voulez pas augmenter la taille de votre bundle, vous voudrez l'utiliser à la place - npmjs.com/package/clsx
Wayne Bloss
34

Vous pouvez utiliser clsx . Je l'ai remarqué utilisé dans les exemples de boutons MUI

Installez-le d'abord:

npm install --save clsx

Puis importez-le dans votre fichier de composant:

import clsx from 'clsx';

Ensuite, utilisez la fonction importée dans votre composant:

<div className={ clsx(classes.container, classes.spacious)}>

Razzlero
la source
5
clsxle paquet est plus petit que classnames, donc je préfère cette solution
Hoang Trinh
2
clsx est inclus dans Material UI, il est donc préférable aux
noms
1
Par le commentaire de Wayne Bloss ci - dessous réponse moins optimale Mini: @material-ui/core now depends on clsx, so if you don't want to increase your bundle size you'll want to use that instead. Donc, +1 pour cette réponse.
cssyphus
20

Pour appliquer plusieurs classes à un composant, encapsulez les classes que vous souhaitez appliquer dans classNames.

Par exemple, dans votre situation, votre code devrait ressembler à ceci,

import classNames from 'classnames';

const styles = theme => ({
  container: {
    display: "flex",
    flexWrap: "wrap"
  },
  spacious: {
    padding: 10
  }
});

<div className={classNames(classes.container, classes.spacious)} />

Assurez-vous d'importer classNames !!!

Jetez un œil à la documentation de l'interface utilisateur matérielle où ils utilisent plusieurs classes dans un composant pour créer un bouton personnalisé

will92
la source
9

Vous pouvez également utiliser la propriété extend (le plugin jss-extend est activé par défaut):

const styles = theme => ({
  container: {
    display: 'flex',
    flexWrap: 'wrap'
  },
  spaciousContainer: {
    extend: 'container',
    padding: 10
  },
});

// ...
<div className={ this.props.classes.spaciousContainer }>
VaclavSir
la source
2
Malheureusement, plus activé par défaut ... votez pour l'activer ici
egerardus
7

Je pense que cela résoudra votre problème:

const styles = theme => ({
 container: {
  display: 'flex',
  flexWrap: 'wrap'
},
 spacious: {
  padding: 10
},
});

et dans le composant de réaction:

<div className={`${classes.container} ${classes.spacious}`}>
Kalim M Vazir
la source
6

Oui, jss-composes vous fournit ceci:

const styles = theme => ({
 container: {
  display: 'flex',
  flexWrap: 'wrap'
},
 spacious: {
  composes: '$container',
  padding: 10
},
});

Et puis vous utilisez simplement classes.spacious.

Oleg Isonen
la source
lors de l'utilisation de plusieurs noms de classe en utilisant compose, cela ne fonctionne pas. codesandbox.io/s/practical-cohen-l6qt5?file=/src/text.js
user970780
2

classNames package peut également être utilisé aussi avancé que:

import classNames from 'classnames';

var arr = ['b', { c: true, d: false }];
classNames('a', arr); // => 'a b c'

let buttonType = 'primary';
classNames({ [`btn-${buttonType}`]: true }); // => 'btn-primary'
Hasan Sefa Ozalp
la source
show error webpack build: Module not found: Erreur: Impossible de résoudre les 'noms de classe' dans
Pranay Soni
1

Vous pouvez ajouter plusieurs classes de chaînes et classes variables ou classes d'accessoires en même temps de cette manière

className={`${classes.myClass}  ${this.props.classes.myClass2} MyStringClass`}

trois cours en même temps

Muzamil301
la source
-1

Si vous souhaitez attribuer plusieurs noms de classe à votre élément, vous pouvez utiliser des tableaux .

Donc, dans votre code ci-dessus, si this.props.classes se résout en quelque chose comme ['container', 'spacieux'], c'est-à-dire si

this.props.classes = ['container', 'spacious'];

vous pouvez simplement l'assigner à div comme

<div className = { this.props.classes.join(' ') }></div>

et le résultat sera

<div class='container spacious'></div>
Praym
la source
êtes-vous sûr que les classes nommées séparées par ,dans le résultat
Pardeep Jain
8
Je ne sais pas pourquoi c'est la réponse acceptée, @Glauber Ramos a raison, Material UI ne fonctionne pas comme ça.
timotgl
-1

Comme déjà mentionné, vous pouvez utiliser l'interpolation de chaîne

className={`${this.props.classes.container}  ${this.props.classes.spacious}`}

Et vous pouvez essayer la classnamesbibliothèque, https://www.npmjs.com/package/classnames

Nemus
la source
Les deux parties de votre réponse ont été fournies plus tôt par d'autres membres. Tout ce que vous avez fait, c'est de les répéter en une seule réponse. -1 (Je vous
suggère de