Hinzufügen mehrerer Klassen in der Material-Benutzeroberfläche mithilfe der Klassenrequisiten

94

Wie füge ich mithilfe der css-in-js-Methode Klassen zu einer Reaktionskomponente hinzu?

Hier ist die Klassenvariable:

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

So habe ich es benutzt:

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

Das Obige funktioniert, aber gibt es eine Möglichkeit, beide Klassen hinzuzufügen, ohne das classNamesnpm-Paket zu verwenden? Etwas wie:

     <div className={ this.props.classes.container + this.props.classes.spacious}>
q3e
quelle
3
Vielleicht fehlt mir etwas, aber können Sie nicht einfach <div className = "container spacious"> tun? Warum müssen Sie es als Eigenschaft übergeben?
Leo Farmer
2
Sie vermissen nur ein Leerzeichen zwischen den beiden Klassennamen.
Shanimal
Ja, wie oben erwähnt, müssen Sie die Klassen nur korrekt mit einem Leerzeichen dazwischen zusammenfassen! Keine zusätzlichen Pakete erforderlich.
Taylor A. Leach

Antworten:

186

Sie können die Zeichenfolgeninterpolation verwenden:

<div className={`${this.props.classes.container} ${this.props.classes.spacious}`}>
klugjo
quelle
5
und denken Sie daran, zwischen den Klassen keine Kommas einzufügen! Ich habe es versehentlich getan und der erste brach lautlos, ohne es eine Weile zu bemerken
Pere
Und zwischen den Klassen muss ein Leerzeichen sein
Yoel
48

Sie können dieses Paket installieren

https://github.com/JedWatson/classnames

und dann benutze es so

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
quelle
3
Dies ist der Ansatz, den Material-UI in einigen Beispielen verwendet und der gut funktioniert. Daher würde ich dies empfehlen.
Craig Myles
2
Dies sollte die akzeptierte Antwort sein. Funktioniert wie erwartet
Howie
2
Ich habe auch diesen Ansatz verwendet. Nützlich nicht nur, um mehrere Klassennamen zu haben, sondern auch, um sie bedingt zu machen.
Mundreißverschluss
4
@material-ui/corehängt jetzt davon ab clsx, also wenn Sie Ihre Bundle-Größe nicht erhöhen möchten, sollten Sie diese stattdessen verwenden - npmjs.com/package/clsx
Wayne Bloss
36

Sie könnten clsx verwenden . Ich habe festgestellt, dass es in den Beispielen für MUI-Schaltflächen verwendet wird

Installieren Sie es zuerst:

npm install --save clsx

Importieren Sie es dann in Ihre Komponentendatei:

import clsx from 'clsx';

Verwenden Sie dann die importierte Funktion in Ihrer Komponente:

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

Razzlero
quelle
5
clsxPaket ist kleiner als classnames, deshalb bevorzuge ich diese Lösung
Hoang Trinh
2
clsx ist in der Material-Benutzeroberfläche enthalten, daher ist es bevorzugter als Klassennamen
DBrown
1
Per Wayne Bloss 'Kommentar unter Minis weniger optimaler Antwort : @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. Also +1 für diese Antwort.
Cssyphus
19

Um mehrere Klassen auf eine Komponente anzuwenden, schließen Sie die Klassen, die Sie anwenden möchten, in classNames ein.

In Ihrer Situation sollte Ihr Code beispielsweise so aussehen:

import classNames from 'classnames';

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

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

Stellen Sie sicher, dass Sie classNames importieren !!!

Schauen Sie sich die Dokumentation zur Material-Benutzeroberfläche an, in der mehrere Klassen in einer Komponente verwendet werden, um eine benutzerdefinierte Schaltfläche zu erstellen

will92
quelle
9

Sie können auch die Extend-Eigenschaft verwenden (das JSS-Extend-Plugin ist standardmäßig aktiviert):

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

// ...
<div className={ this.props.classes.spaciousContainer }>
VaclavSir
quelle
2
Leider nicht mehr standardmäßig aktiviert ... stimmen Sie ab, um hier
egerardus
7

Ich denke, das wird Ihr Problem lösen:

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

und in Reaktionskomponente:

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

Ja, jss-composes bietet Ihnen Folgendes:

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

Und dann benutzt du einfach Klassen.

Oleg Isonen
quelle
Bei Verwendung von mehreren Klassennamen mit compose funktioniert dies nicht. Codesandbox.io/s/practical-cohen-l6qt5?file=/src/text.js
user970780
2

classNames Paket kann auch so fortgeschritten verwendet werden wie:

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
quelle
show error webpack build: Modul nicht gefunden: Fehler: 'Klassennamen' können in
Pranay Soni
1

Auf diese Weise können Sie mehrere Zeichenfolgenklassen und Variablenklassen oder Requisitenklassen gleichzeitig hinzufügen

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

drei Klassen gleichzeitig

Muzamil301
quelle
-1

Wenn Sie Ihrem Element mehrere Klassennamen zuweisen möchten , können Sie Arrays verwenden .

Wenn this.props.classes in Ihrem obigen Code in etwas wie ['container', 'spacious'] aufgelöst wird, dh if

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

Sie können es einfach div als zuweisen

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

und Ergebnis wird sein

<div class='container spacious'></div>
Praym
quelle
,
Sind
8
Ich bin mir nicht sicher, warum dies die akzeptierte Antwort ist. @Glauber Ramos hat Recht. Die Material-Benutzeroberfläche funktioniert so nicht.
Timotgl
-1

Wie bereits erwähnt, können Sie die Zeichenfolgeninterpolation verwenden

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

Sie können auch die classnamesBibliothek https://www.npmjs.com/package/classnames ausprobieren

Nemus
quelle
Beide Teile Ihrer Antwort wurden früher von anderen Mitgliedern bereitgestellt. Alles, was Sie getan haben, war, sie in einer einzigen Antwort zu wiederholen. -1 (Schlagen Sie vor, diese Antwort zu löschen und Ihre 2 Punkte wiederherzustellen)
cssyphus