Jak dodać wiele klas w Material UI przy użyciu właściwości klas

92

Jak dodać wiele komponentów za pomocą metody css-in-js do dodawania klas do komponentu reagującego?

Oto zmienna klas:

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

Oto jak to wykorzystałem:

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

Powyższe działa, ale czy jest sposób na dodanie obu klas bez użycia classNamespakietu npm? Coś jak:

     <div className={ this.props.classes.container + this.props.classes.spacious}>
q3e
źródło
3
Może czegoś mi brakuje, ale czy nie możesz po prostu zrobić <div className = "container przestronny"> Dlaczego musisz przekazać to jako właściwość?
Leo Farmer,
2
po prostu brakuje spacji między dwiema nazwami klas.
Shanimal
Tak, jak wspomniano powyżej, wystarczy poprawnie połączyć klasy ze spacją! Nie ma potrzeby stosowania dodatkowych pakietów.
Taylor A. Leach

Odpowiedzi:

180

możesz użyć interpolacji ciągów:

<div className={`${this.props.classes.container} ${this.props.classes.spacious}`}>
klugjo
źródło
5
i pamiętaj, aby nie dodawać przecinków między zajęciami! Zrobiłem przez pomyłkę i pierwsza zepsuła się cicho, nie zauważając na chwilę
Pere
A między zajęciami musi być odstęp
Yoel
49

możesz zainstalować ten pakiet

https://github.com/JedWatson/classnames

a następnie użyj go w ten sposób

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
źródło
3
Jest to podejście stosowane przez Material-UI w niektórych ich przykładach i działa dobrze, więc polecam to.
Craig Myles,
2
To powinna być akceptowana odpowiedź. Działa zgodnie z oczekiwaniami
Howie
2
Używam również tego podejścia. Przydatne nie tylko do posiadania wielu nazw klas, ale także do uczynienia ich warunkowymi.
zamek do ust
4
@material-ui/coreteraz zależy od clsx, więc jeśli nie chcesz zwiększać rozmiaru pakietu, zechcesz go zamiast tego użyć - npmjs.com/package/clsx
Wayne
34

Możesz użyć clsx . Zauważyłem, że został użyty w przykładach przycisków MUI

Najpierw zainstaluj:

npm install --save clsx

Następnie zaimportuj go do pliku komponentu:

import clsx from 'clsx';

Następnie użyj zaimportowanej funkcji w swoim komponencie:

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

Razzlero
źródło
5
clsxpaczka jest mniejsza niż classnames, więc wolę to rozwiązanie
Hoang Trinh
2
clsx jest zawarty w Material UI, więc jest bardziej preferowany niż
nazwy klas
1
Za komentarzu Wayne Bloss poniżej mniej optymalną odpowiedź 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. Więc +1 za tę odpowiedź.
cssyphus
20

Aby zastosować wiele klas do składnika, zawiń klasy, które chcesz zastosować, w ClassNames.

Na przykład w Twojej sytuacji kod powinien wyglądać następująco:

import classNames from 'classnames';

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

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

Upewnij się, że importujesz nazwy klas !!!

Zapoznaj się z dokumentacją interfejsu użytkownika, w której używają wielu klas w jednym komponencie, aby utworzyć niestandardowy przycisk

will92
źródło
9

Możesz także skorzystać z właściwości Extend (wtyczka jss-Extend jest domyślnie włączona):

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

// ...
<div className={ this.props.classes.spaciousContainer }>
VaclavSir
źródło
2
Niestety, domyślnie nie jest już włączone ... głosuj, aby włączyć tutaj
egerardus
7

Myślę, że to rozwiąże twój problem:

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

oraz w komponencie reakcyjnym:

<div className={`${classes.container} ${classes.spacious}`}>
Kalim M Vazir
źródło
6

Tak, jss-composes zapewnia to:

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

A potem po prostu używasz classes.spacious.

Oleg Isonen
źródło
podczas używania wielu nazw klas za pomocą tworzenia wiadomości to nie działa. codeandbox.io/s/practical-cohen-l6qt5?file=/src/text.js
user970780
2

classNames Pakiet może być również używany tak zaawansowany, jak:

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
źródło
show error kompilacja pakietu webpack: Nie znaleziono modułu: Błąd: nie można rozpoznać nazw klas w
Pranay Soni
1

W ten sposób możesz dodać wiele klas ciągów i klas zmiennych lub klas właściwości

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

trzy zajęcia w tym samym czasie

Muzamil301
źródło
-1

Jeśli chcesz przypisać wiele nazw klas do swojego elementu, możesz użyć tablic .

Tak więc w powyższym kodzie, jeśli this.props.classes jest tłumaczone na coś takiego jak ['container', 'przestronny'], tj.

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

możesz po prostu przypisać go do div as

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

a wynik będzie

<div class='container spacious'></div>
Praym
źródło
Czy na pewno klasy nazwane rozdzielone przez ,w rezultacie
Pardeep Jain,
8
Nie jestem pewien, dlaczego jest to akceptowana odpowiedź, @Glauber Ramos ma rację, Material UI nie działa w ten sposób.
timotgl
-1

Jak już wspomniano, możesz użyć interpolacji ciągów

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

Możesz też wypróbować classnamesbibliotekę https://www.npmjs.com/package/classnames

Nemus
źródło
Obie części Twojej odpowiedzi zostały wcześniej udzielone przez innych członków. Wszystko, co zrobiłeś, to powtórzyć je w jednej odpowiedzi. -1 (Zaproponuj usunięcie tej odpowiedzi i odzyskanie 2 punktów)
cssyphus