Як додати кілька класів в інтерфейсі матеріалу за допомогою реквізиту класів


92

Використання методу css-in-js для додавання класів до реакційного компонента, як мені додати кілька компонентів?

Ось змінна класів:

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

Ось як я ним користувався:

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

Вищевказане працює, але чи є спосіб додати обидва класи, не використовуючи classNamesпакет npm? Щось на зразок:

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

3
Можливо, я чогось пропускаю, але чи не можете ви просто зробити <div className = "container просторовий"> Чому вам потрібно передавати це як властивість?
Лео Фермер

2
вам просто бракує пробілу між двома іменами класу.
Шанімал,

Так, як зазначено вище, вам просто потрібно правильно поєднати класи разом із пробілом між ними! Не потрібно ніяких додаткових пакетів.
Тейлор А. Ліч

Відповіді:


180

Ви можете використовувати інтерполяцію рядків:

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

5
і пам’ятайте, що не слід додавати коми між класами! Я зробив це помилково, і перший зламався мовчки, не помітивши на деякий час
Пере

І між класами повинен бути простір
Йоел

49

Ви можете встановити цей пакет

https://github.com/JedWatson/classnames

а потім використовувати його так

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
Це підхід, який Material-UI використовує в деяких прикладах, і він працює добре, тому я б рекомендував це.
Craig Myles

2
Це має бути прийнятою відповіддю. Працює, як очікувалося
Howie

2
Також використовував цей підхід. Корисно не тільки для того, щоб мати кілька імен класів, але й для того, щоб зробити його умовним.
mouthzipper

4
@material-ui/coreтепер залежить від clsx, тому, якщо ви не хочете збільшувати розмір набору, ви захочете використовувати це - npmjs.com/package/clsx
Wayne Bloss

34

Ви можете використовувати clsx . Я помітив, що це використовується в прикладах кнопок MUI

Спочатку встановіть його:

npm install --save clsx

Потім імпортуйте його у файл компонента:

import clsx from 'clsx';

Потім використовуйте імпортовану функцію у своєму компоненті:

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


5
clsxпакет менший за classnames, тому я віддаю перевагу такому рішенню
Хоанг Трін,

2
clsx включений до інтерфейсу матеріалу, тому його кращий за
назви

1
За коментарем Wayne Блоссом нижче менш оптимальну відповідь 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. Отже, +1 для цієї відповіді.
cssyphus

20

Щоб застосувати до компонента кілька класів, оберніть класи, які ви хочете застосувати, у classNames.

Наприклад, у вашій ситуації ваш код повинен виглядати так,

import classNames from 'classnames';

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

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

Переконайтеся, що ви імпортуєте classNames !!!

Погляньте на документацію щодо користувацького інтерфейсу, де вони використовують кілька класів в одному компоненті, щоб створити індивідуальну кнопку


9

Ви також можете використовувати властивість extension (плагін jss-extension увімкнено за замовчуванням):

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

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

2
На жаль, більше не ввімкнено за замовчуванням ... голосуйте, щоб увімкнути тут
egerardus

7

Я думаю, це вирішить вашу проблему:

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

і в реакційному компоненті:

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

6

Так, jss-composed надає вам таке:

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

І тоді ви просто використовуєте classes.spacious.


при використанні декількох назв класів за допомогою compose це не працює. codesandbox.io/s/practical-cohen-l6qt5?file=/src/text.js
user970780

2

classNames Пакет також може бути використаний як просунутий як:

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'

показати помилку збірки веб-пакета: Модуль не знайдено: Помилка: Не вдається вирішити "
імена

1

Таким чином, ви можете одночасно додати кілька класів рядків та класи змінних чи реквізиту

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

три класи одночасно


-1

Якщо ви хочете призначити своєму елементу кілька імен класів , ви можете використовувати масиви .

Отже, у вашому коді вище, якщо this.props.classes вирішує щось на зразок ['контейнер', 'просторий'], тобто якщо

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

Ви можете просто призначити його як div

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

і результат буде

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

Ви впевнені, класи, названі розділеними ,результатом,
Pardeep Jain

8
Не впевнений, чому це прийнята відповідь, @Glauber Ramos має рацію, інтерфейс Material не працює так.
timotgl

-1

Як уже зазначалося, ви можете використовувати інтерполяцію рядків

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

А ви можете спробувати classnamesбібліотеку, https://www.npmjs.com/package/classnames


Обидві частини вашої відповіді були надані раніше іншими членами. Все, що ви зробили, - це повторити їх в одній відповіді. -1 (Пропоную вам видалити цю відповідь і відновити свої 2 бали)
cssyphus
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.