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}>

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}`}>

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'

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)}>


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


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 }>

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}`}>


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'

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


-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>

¿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


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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.