Class props kullanarak Material UI'de birden çok sınıf ekleme


92

Bir react bileşenine sınıf eklemek için css-in-js yöntemini kullanarak birden çok bileşeni nasıl eklerim?

İşte sınıflar değişkeni:

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

İşte onu nasıl kullandım:

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

Yukarıdakiler çalışır, ancak classNamesnpm paketini kullanmadan her iki sınıfı da eklemenin bir yolu var mı? Gibi bir şey:

     <div className={ this.props.classes.container + this.props.classes.spacious}>

3
Belki bir şeyi kaçırıyorum, ancak bunu yapamaz mısın <div className = "container wide"> Neden onu bir özellik olarak geçirmeniz gerekiyor?
Leo Farmer

2
sadece iki sınıf adı arasında bir boşluk eksik.
Shanimal

Evet, yukarıda belirtildiği gibi, sınıfları arada bir boşluk bırakarak doğru bir şekilde birleştirmeniz yeterlidir! Ek paketlere gerek yok.
Taylor

Yanıtlar:


180

dize enterpolasyonunu kullanabilirsiniz:

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

5
ve sınıflar arasına virgül eklememeyi unutmayın! Yanlışlıkla yaptım ve ilki bir süre fark etmeden sessizce kırıldı
Pere

Ve sınıflar arasında bir boşluk olmalı
Yoel

49

bu paketi kurabilirsin

https://github.com/JedWatson/classnames

ve sonra bunu böyle kullan

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'

3
Bu, Material-UI'nin bazı örneklerinde kullandığı yaklaşımdır ve iyi çalışıyor, bu yüzden bunu tavsiye ederim.
Craig Myles

2
Kabul edilen cevap bu olmalıdır. Beklendiği gibi çalışıyor
Howie

2
Bu yaklaşımı da kullanıyorum. Sadece birden fazla sınıf adına sahip olmak için değil, aynı zamanda onu koşullu yapmak için de kullanışlıdır.
mouthzipper

4
@material-ui/coreartık bağlıdır clsx, bu nedenle paket boyutunuzu artırmak istemiyorsanız, bunun yerine onu kullanmak isteyeceksiniz - npmjs.com/package/clsx
Wayne Bloss

34

Clsx kullanabilirsiniz . MUI düğme örneklerinde kullanıldığını fark ettim

Önce kurun:

npm install --save clsx

Ardından bunu bileşen dosyanıza içe aktarın:

import clsx from 'clsx';

Ardından, bileşeninizde içe aktarılan işlevi kullanın:

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


5
clsxpaket daha küçük classnames, bu yüzden bu çözümü tercih ediyorum
Hoang Trinh

2
clsx, Material UI'ye dahildir, bu nedenle sınıf
adlarından

1
Mini'nin az-optimal cevap aşağıda Wayne Blöss Başına yorum: @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. Yani, bu cevap için +1.
cssyphus

20

Bir bileşene birden çok sınıfın uygulanmasını sağlamak için, sınıf adları içinde uygulamak istediğiniz sınıfları kaydırın.

Örneğin, sizin durumunuzda, kodunuz şöyle görünmelidir,

import classNames from 'classnames';

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

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

ClassNames'i içe aktardığınızdan emin olun !!!

Özelleştirilmiş bir düğme oluşturmak için tek bir bileşende birden çok sınıf kullandıkları malzeme kullanıcı arabirimi belgelerine bir göz atın


9

Ayrıca, ext özelliğini de kullanabilirsiniz ( jss-extended eklentisi varsayılan olarak etkindir):

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

// ...
<div className={ this.props.classes.spaciousContainer }>

2
Maalesef, artık varsayılan olarak etkin değil ... buradan
egerardus

7

Sanırım bu sorununuzu çözecek:

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

ve reaksiyon bileşeninde:

<div className={`${classes.container} ${classes.spacious}`}>


2

classNames paket aynı zamanda gelişmiş olarak da kullanılabilir:

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'

hatayı göster web paketi derlemesi: Modül bulunamadı: Hata: 'sınıf
adları

1

Bu şekilde aynı anda birden çok dize sınıfı ve değişken sınıfı veya sahne sınıfı ekleyebilirsiniz.

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

aynı anda üç sınıf


-1

İsterseniz birden sınıf atamak için elemana isimleri yapabilirsiniz diziler kullanın .

Dolayısıyla, yukarıdaki kodunuzda this.props.classes ['kapsayıcı', 'geniş'] gibi bir şeye çözümlenirse, yani

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

basitçe div olarak atayabilirsiniz

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

ve sonuç olacak

<div class='container spacious'></div>

,sonuçta sınıfların ayrıldığından emin misiniz
Pardeep Jain

8
Bunun neden kabul edilen cevap olduğundan emin değilim, @Glauber Ramos haklı, Material UI böyle çalışmıyor.
timotgl

-1

Daha önce belirtildiği gibi, dize enterpolasyonunu kullanabilirsiniz.

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

Ve classnameskitaplığı deneyebilirsiniz , https://www.npmjs.com/package/classnames


Cevabınızın her iki kısmı da daha önce diğer üyeler tarafından sağlandı. Tek yaptığınız onları tek bir cevapla tekrar etmekti. -1 (Bu yanıtı silmenizi ve 2
puanınızı
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.