Cómo agregar múltiples clases en Material UI usando los accesorios de clases

92

Usando el método css-in-js para agregar clases a un componente de reacción, ¿cómo agrego varios componentes?

Aquí está la variable de clases:

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

Así es como lo usé:

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

Lo anterior funciona, pero ¿hay alguna manera de agregar ambas clases sin usar el classNamespaquete npm? Algo como:

     <div className={ this.props.classes.container + this.props.classes.spacious}>
q3e
fuente
3
Tal vez me falte algo, pero ¿no puedes simplemente hacer <div className = "container espacioso"> ¿Por qué necesitas pasarlo como una propiedad?
Leo Farmer
2
solo falta un espacio entre los dos classNames.
Shanimal
Sí, como se indicó anteriormente, ¡solo necesita concaminar las clases juntas correctamente con un espacio intermedio! No es necesario ningún paquete adicional.
Taylor A. Leach

Respuestas:

180

puede utilizar la interpolación de cadenas:

<div className={`${this.props.classes.container} ${this.props.classes.spacious}`}>
klugjo
fuente
5
¡Y recuerde no agregar comas entre clases! Lo hice por error y el primero se rompió en silencio sin darme cuenta por un tiempo
Pere
Y debe haber un espacio entre las clases
Yoel
49

puedes instalar este paquete

https://github.com/JedWatson/classnames

y luego úsalo así

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
fuente
3
Este es el enfoque que utiliza Material-UI en algunos de sus ejemplos, y funciona bien, así que lo recomiendo.
Craig Myles
2
Esta debería ser la respuesta aceptada. Funciona como se esperaba
Howie
2
También he estado usando este enfoque. Útil no solo para tener varios nombres de clase, sino también para hacerlo condicional.
cremallera en la boca
4
@material-ui/coreahora depende de clsx, por lo que si no desea aumentar el tamaño de su paquete, querrá usarlo en su lugar - npmjs.com/package/clsx
Wayne Bloss
34

Podrías usar clsx . Noté que se usa en los ejemplos de botones MUI

Primero instálalo:

npm install --save clsx

Luego impórtelo en su archivo de componente:

import clsx from 'clsx';

Luego use la función importada en su componente:

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

Razzlero
fuente
5
clsxel paquete es más pequeño que classnames, por lo que prefiero esta solución
Hoang Trinh
2
clsx está incluido en Material UI, por lo que es más preferido que los
nombres
1
Por Wayne comentario Bloss' por debajo de respuesta inferior a la óptima del 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. Entonces, +1 para esta respuesta.
cssyphus
20

Para tener varias clases aplicadas a un componente, envuelva las clases que le gustaría aplicar dentro de classNames.

Por ejemplo, en su situación, su código debería verse así,

import classNames from 'classnames';

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

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

¡Asegúrate de importar classNames!

Eche un vistazo a la documentación de la interfaz de usuario de material donde usan múltiples clases en un componente para crear un botón personalizado

will92
fuente
9

También puede usar la propiedad extend (el complemento jss-extend está habilitado de forma predeterminada):

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

// ...
<div className={ this.props.classes.spaciousContainer }>
VaclavSir
fuente
2
Desafortunadamente, ya no está habilitado por defecto ... vote para habilitar aquí
egerardus
7

Creo que esto resolverá tu problema:

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

y en el componente de reacción:

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

Sí, jss-composes le proporciona esto:

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

Y luego solo usa classes.spacious.

Oleg Isonen
fuente
mientras usa varios nombres de clase usando componer, no funciona. codesandbox.io/s/practical-cohen-l6qt5?file=/src/text.js
user970780
2

classNames El paquete también se puede utilizar tan avanzado como:

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
fuente
muestre el error de compilación del paquete web: Módulo no encontrado: Error: No se pueden resolver los 'nombres de clase' en
Pranay Soni
1

Puede agregar varias clases de cadenas y clases de variables o clases de accesorios al mismo tiempo de esta manera

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

tres clases al mismo tiempo

Muzamil301
fuente
-1

Si desea asignar varios nombres de clase a su elemento, puede usar matrices .

Entonces, en su código anterior, si this.props.classes se resuelve en algo como ['contenedor', 'espacioso'], es decir, si

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

simplemente puede asignarlo a div como

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

y el resultado será

<div class='container spacious'></div>
Praym
fuente
¿Estás seguro de que las clases se nombran separadas por ,en el resultado?
Pardeep Jain
8
No estoy seguro de por qué esta es la respuesta aceptada, @Glauber Ramos tiene razón, Material UI no funciona así.
timotgl
-1

Como ya se mencionó, puede usar la interpolación de cadenas

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

Y puede probar la classnamesbiblioteca, https://www.npmjs.com/package/classnames

Nemus
fuente
Ambas partes de su respuesta fueron proporcionadas anteriormente por otros miembros. Todo lo que hizo fue repetirlos en una sola respuesta. -1 (Sugiero que elimine esta respuesta y recupere sus 2 puntos)
cssyphus