Material-ui: ¿Puede withStyles pasar accesorios al objeto de estilos?

Creado en 17 oct. 2017  ·  54Comentarios  ·  Fuente: mui-org/material-ui

Actualmente, estoy desarrollando un componente que requiere objetos tanto de props como de temas.

Al principio, funciona muy bien con el objeto de tema.

const styles = theme => ({
  title: {
    ...theme.typography.headline,
    textAlign: 'center',
    padding: '8px 16px',
    margin: 0,
    color: theme.palette.common.white,
    backgroundColor: theme.palette.primary[500],
  },

withStyles(styles, { withTheme: true })(Component);
....

Pero también necesito acceso a accesorios en el objeto de estilos.

Intenté el ejemplo pero no funciona.

{
 ....
display: (props) => props.display
}

Termino combinando react-jss y withTheme para hacer eso

import { withTheme } from 'material-ui/styles';
import injectSheet from 'react-jss';

function withStyles(styles, Component) {
  return withTheme()(injectSheet(styles)(Component));
}

export default withStyles;

....

const styles = {
  title: {
    display: (props) => props.display,
    textAlign: 'center',
    padding: '8px 16px',
    margin: 0,
    color: ({ theme }) => theme.palette.common.white,
    backgroundColor: ({ theme }) => theme.palette.primary[500],
  },

Funciona pero realmente extraño

  title: {
    ...theme.typography.headline,
duplicate

Comentario más útil

@oliviertassinari ¡ Es muy reconfortante saber que considerará priorizar esto! Esto facilitaría mucho la personalización de los componentes. Por ejemplo, me gustaría tener una casilla de verificación con un tamaño configurable (es decir, ancho y alto en píxeles):

<CustomCheckbox size={16} />

Si pudiéramos acceder a props en styles , esto sería muy simple:

const styles = {
  root: {
    width: props => props.size,
    height: props => props.size
  }
}

o

const styles = props => ({
  root: {
    width: props.size,
    height: props.size
  }
})

y luego:

const CustomCheckbox = ({size, classes}) => <Checkbox className={classes.root} />;

export default withStyles(styles)(CustomCheckbox);

Por ahora, ¿tiene alguna recomendación sobre cómo deberíamos abordar este tipo de casos de uso? ¿O tiene alguna estimación de cuándo podría agregar soporte para acceder a accesorios cuando use withStyles?

Todos 54 comentarios

Probablemente deberíamos poder abordar el problema haciendo Material-UI usando la misma clave de contexto que react-jss: https://github.com/cssinjs/theming/blob/master/src/channel.js#L1.
Además, eche un vistazo al # 7633

Tengo un PR listo con un ejemplo de interoperabilidad react-jss. Agregaré eso en los documentos. cc @kof

@oliviertassinari, ¿la resolución de esto significa que ahora debería ser posible obtener acceso a los accesorios dentro de la definición de estilos? No tengo claro cómo ...

@pelotom no, withStyles no tiene acceso a las propiedades. Pero dada la cantidad de personas que piden esta función. Es algo que puedo priorizar, después de las correcciones de errores. Puede usar injectSheet HOC, pero abre la puerta a múltiples problemas: pérdida de memoria, recarga en caliente rota, sin composición classes , sin acceso de referencia interna, manejo de anidamiento de temas roto. Al menos, son algunos de los problemas a los que me he enfrentado en el pasado y motivaron mi reescritura. Creo que paso a paso se abordarán esas cuestiones.

@oliviertassinari ¡ Es muy reconfortante saber que considerará priorizar esto! Esto facilitaría mucho la personalización de los componentes. Por ejemplo, me gustaría tener una casilla de verificación con un tamaño configurable (es decir, ancho y alto en píxeles):

<CustomCheckbox size={16} />

Si pudiéramos acceder a props en styles , esto sería muy simple:

const styles = {
  root: {
    width: props => props.size,
    height: props => props.size
  }
}

o

const styles = props => ({
  root: {
    width: props.size,
    height: props.size
  }
})

y luego:

const CustomCheckbox = ({size, classes}) => <Checkbox className={classes.root} />;

export default withStyles(styles)(CustomCheckbox);

Por ahora, ¿tiene alguna recomendación sobre cómo deberíamos abordar este tipo de casos de uso? ¿O tiene alguna estimación de cuándo podría agregar soporte para acceder a accesorios cuando use withStyles?

¡Gracias @oliviertassinari ! Esperaba poder lograr esto usando withStyles , pero los estilos en línea funcionarán muy bien. Y el hecho de que lo recomiende aquí + en los documentos me hace sentir muy seguro con esta decisión. ¡Gracias de nuevo!

Sería bueno poder pasar un prop (image src) al estilo para un backgroundImage

Envolvería withStyle

const withStylesProps = styles =>
  Component =>
    props => {
      console.log(props);
      const Comp = withStyles(styles(props))(Component);
      // return <div>lol</div>;
      return <Comp {...props} />;
    };

const styles = props => ({
  foo: {
    height: `${props.y || 50}px`,
  }
});

export default withStylesProps(styles)(
  props => (
    <div className={props.classes.foo} style={{ ...props.style, background: 'yellow' }}>
      <h1>Hello!</h1>
    </div>
  )
);

demostración: https://codesandbox.io/s/k2y01rj3w7

(Me sorprende ^ funciona sin ThemeProvider y JssProvider configurados https://codesandbox.io/s/q6v7krx6, ah, lo inicializa)

@caub Está funcionando, pero debes tener cuidado con este patrón. El CSS inyectado crecerá con la cantidad de instancias del componente. Es un duplicado del # 7633. No he profundizado en el tema. Pero creo que la versión de @kof usa alguna optimización de rendimiento.

@caub ¡ Gracias por compartir!

@oliviertassinari hay esto https://github.com/cssinjs/react-jss/blob/master/readme.md#dynamic -values ​​en react-jss, me pregunto por qué no se puede usar en material-ui. También entiendo su punto en el que dice que el style prop en línea es perfecto para valores dinámicos, pero es mejor tener todas las definiciones de estilos en los mismos lugares. También hay https://github.com/airbnb/react-with-styles que manejarían className y style para estilos dinámicos más eficientes

Estoy enfrentando el mismo problema, ¿alguien puede ayudarme?
`importar React de 'reaccionar';
importar PropTypes de 'prop-types';
importar {withStyles} de 'material-ui / styles';
importar Cajón de 'material-ui / Drawer';
importar AppBar desde 'material-ui / AppBar';
importar la barra de herramientas de 'material-ui / Toolbar';
importar Lista de 'material-ui / List';
importar tipografía de 'material-ui / Typography';
importar IconButton desde 'material-ui / IconButton';
importar Oculto de 'material-ui / Hidden';
importar Divider de 'material-ui / Divider';
importar MenuIcon desde 'material-ui-icons / Menu';
importar {mailFolderListItems, otherMailFolderListItems} desde './tileData';

ancho de cajón const = 240;

estilos const = tema => ({
raíz: {
ancho: '100%',
altura: 430,
marginTop: theme.spacing.unit * 3,
zIndex: 1,
desbordamiento: 'oculto',
},
appFrame: {
posición: 'relativo',
pantalla: 'flex',
ancho: '100%',
altura: '100%',
},
appBar: {
posición: 'absoluta',
marginLeft: drawerWidth,
[theme.breakpoints.up ('md')]: {
ancho: calc(100% - ${drawerWidth}px) ,
},
},
navIconHide: {
[theme.breakpoints.up ('md')]: {
pantalla: 'ninguno',
},
},
drawerHeader: theme.mixins.toolbar,
drawerPaper: {
ancho: 250,
[theme.breakpoints.up ('md')]: {
width: drawerWidth,
posición: 'relativo',
altura: '100%',
},
},
contenido: {
backgroundColor: theme.palette.background.default,
ancho: '100%',
padding: theme.spacing.unit * 3,
altura: 'calc (100% - 56px)',
marginTop: 56,
[theme.breakpoints.up ('sm')]: {
altura: 'calc (100% - 64px)',
marginTop: 64,
},
},
});

export class ResponsiveDrawer extiende React.Component {
estado = {
mobileOpen: false,
};

handleDrawerToggle = () => {
this.setState ({mobileOpen:! this.state.mobileOpen});
};

render () {
const {clases, tema} = this.props;

const drawer = (
  <div>
    <div className={classes.drawerHeader} />
    <Divider />
    <List>{mailFolderListItems}</List>
    <Divider />
    <List>{otherMailFolderListItems}</List>
  </div>
);

return (
  <div className={classes.root}>
    <div className={classes.appFrame}>
      <AppBar className={classes.appBar}>
        <Toolbar>
          <IconButton
            color="inherit"
            aria-label="open drawer"
            onClick={this.handleDrawerToggle}
            className={classes.navIconHide}
          >
            <MenuIcon />
          </IconButton>
          <Typography variant="title" color="inherit" noWrap>
            Responsive drawer
          </Typography>
        </Toolbar>
      </AppBar>
      <Hidden mdUp>
        <Drawer
          variant="temporary"
          anchor={theme.direction === 'rtl' ? 'right' : 'left'}
          open={this.state.mobileOpen}
          classes={{
            paper: classes.drawerPaper,
          }}
          onClose={this.handleDrawerToggle}
          ModalProps={{
            keepMounted: true, // Better open performance on mobile.
          }}
        >
          {drawer}
        </Drawer>
      </Hidden>
      <Hidden smDown implementation="css">
        <Drawer
          variant="permanent"
          open
          classes={{
            paper: classes.drawerPaper,
          }}
        >
          {drawer}
        </Drawer>
      </Hidden>
      <main className={classes.content}>
        <Typography noWrap>{'You think water moves fast? You should see ice.'}</Typography>
      </main>
    </div>
  </div>
);

}
}

ResponsiveDrawer.propTypes = {
clases: PropTypes.object.isRequired,
tema: PropTypes.object.isRequired,
};

exportar por defecto withStyles (estilos) (ResponsiveDrawer);
'

screen shot 2018-02-13 at 3 27 41 am

El CSS inyectado crecerá con la cantidad de instancias del componente.

@oliviertassinari CSS inyectado crecerá + - de la misma manera que html crecería con estilos en línea. Los estilos estáticos se representan en hojas independientes y se reutilizan en todas las instancias de componentes.

Me gustó esto, aunque con el componente sin estado volverá a renderizar el withStyle de render a render , podemos evitarlo utilizando el componente puro completo.

import React from 'react';
import {
  withStyles,
  Grid,
  CircularProgress
} from 'material-ui';

const PreloadComponent = props => {
  const { classes,size } = props;
  return (
    <Grid className={classes.container} container justify={'center'} alignItems={'center'}>
      <CircularProgress size={size}/>
    </Grid>
  )
};

const StyleWithThemeProps = (props) => {
  return withStyles(theme => ({
    container: {
      paddingTop: props.size*2 || 50,
      paddingBottom: props.size*2 || 50,
    }
  }),{withTheme: true})(PreloadComponent)
};

const Preload = props => {
  const { size } = props;
  const WithStylesPreloadComponent = StyleWithThemeProps(props);
  return (
    <WithStylesPreloadComponent {...props}/>
  )
};

Preload.defaultProps = {
  size: 20
};

export default Preload;

Podemos usar el componente puro completo para evitar la actualización.

const PreloadComponent = props => {
  const { classes,size } = props;
  return (
    <Grid className={classes.container} container justify={'center'} alignItems={'center'}>
      <CircularProgress size={size}/>
    </Grid>
  )
};

const StyleWithThemeProps = (props) => {
  return withStyles(theme => ({
    container: {
      paddingTop: props.size*2 || 50,
      paddingBottom: props.size*2 || 50,
    }
  }),{withTheme: true})(PreloadComponent)
};

class PreloadFull extends React.PureComponent {

  constructor(props,context) {
    super(props);
  }

  componentWillMount() {
    this.StyledPreloadFull = StyleWithThemeProps(this.props);
  }

  componentWillUpdate(nextProps) {
    this.StyledPreloadFull = StyleWithThemeProps(nextProps);
  }

  render() {
    const { StyledPreloadFull,props } = this;
    return (
      <StyledPreloadFull {...props}/>
    );
  }
}

PreloadFull.defaultProps = {
  size: 20
};

export default PreloadFull;

@ up209d Funciona, pero es bastante doloroso, intentaré modificar withStyles , para usar más directamente https://github.com/cssinjs/react-jss que puede pasar props en valores

@SrikanthChebrolu, ¿ podría mover su mensaje a un tema diferente, ya que no está dentro del tema?

¿Solo tienes curiosidad por saber cuál es el estado de esto? He estado leyendo este problema, los documentos JSS, material-ui docs, y aún no he encontrado una solución para Mui + Jss + TypeScript que no requiera que use estilos en línea. Poner algunos estilos en línea es a veces inevitable, pero en mi caso hay varios estilos que tienen muchos estados diferentes, todos dependiendo del tema y los accesorios juntos: decepcionado:

@chazsolo Hola Chaz, en realidad puedes usar injectSheet de react-jss lugar de withStyles de mui . De esa manera, puede tener props y theme .

import injectSheet from 'react-jss';

const styles = theme => ({
  container: {
     color: props => theme.palette[props.color || 'primary'].main
  }
});

...

export default injectSheet(styles)(AnyComponent);
import { JssProvider, jss, createGenerateClassName } from 'react-jss/lib';
import { MuiThemeProvider } from 'material-ui';

const generateClassName = createGenerateClassName();

...

<JssProvider jss={jss} generateClassName={generateClassName}>
  <MuiThemeProvider theme={props.theme} sheetsManager={new Map()}>
    <App/>
  </MuiThemeProvider>
</JssProvider>

@chazsolo Creo que quieres seguir este tema https://github.com/cssinjs/jss/issues/682

Gracias @kof y @ up209d : se suscribieron y renunciaron al ejemplo de up209d.

@ up209d
Desafortunadamente, no creo que eso funcione para mí. Implementé lo que sugirió y puedo ver los accesorios dentro de la llamada a la función dentro del objeto styles , pero sigo recibiendo errores. ¿Me faltan tipos? Estoy ampliando WithStyles en interfaces de accesorios para tener acceso al objeto classes en accesorios (ahora me pregunto si ese es el problema al que se hace referencia en https://github.com/mui- org / material-ui / issues / 8726 # issuecomment-337482040)

TS2344: Type '(theme: ITheme) => { arc: { stroke: string; strokeWidth: (props: any) => string | number; }; arcM...' does not satisfy the constraint 'string | Record<string, CSSProperties> | StyleRulesCallback<string>'.
  Type '(theme: ITheme) => { arc: { stroke: string; strokeWidth: (props: any) => string | number; }; arcM...' is not assignable to type 'StyleRulesCallback<string>'.
    Type '{ arc: { stroke: string; strokeWidth: (props: any) => string | number; }; arcMovement: { strokeDa...' is not assignable to type 'Record<string, CSSProperties>'.
      Property 'arc' is incompatible with index signature.
        Type '{ stroke: string; strokeWidth: (props: any) => string | number; }' is not assignable to type 'CSSProperties'.
          Types of property 'strokeWidth' are incompatible.
            Type '(props: any) => string | number' is not assignable to type 'string | number | undefined'.
              Type '(props: any) => string | number' is not assignable to type 'number'.

Mi tema se parece a:

import { ITheme } from '...';

export default (theme: ITheme) => ({
  arc: {
    // ...
    strokeWidth: (props: any): number | string => {
      // this logs the correct data I'm expecting
      console.log(props.data[0].properties.name)
      return 1.5
    }
  },
  arcMovement: {
    // ...
  },
})

Lo interesante es que cuando uso el objeto classes dentro de mi componente, arc y arcMovement son propiedades válidas:

// from Chrome console
{
  arc: "Arcs-arc-0-2-1 Arcs-arc-0-2-3",
  arcMovement: "Arcs-arcMovement-0-2-2"
}

Actualizar

Pude hacer que esto funcionara, pero como se señaló en el comentario anterior, tuve que eliminar todas las referencias a WithStyles , withStyles , y pierdo classes composición y tema anidamiento. Voy a darle un descanso ahora y solo vigilaré los hilos. ¡Gracias por toda la ayuda!

@chazsolo Hola Chaz, no estoy seguro pero es que quieres acceder a classes dentro del props del objeto style . Si es así, creo que es imposible ya que el classes solo está disponible después de que jss procesó el objeto style , ¿cómo se puede acceder a classes antes de un proceso de creación classes incluso no se ha activado?

Creo que @caub ya proporcionó una solución. Simplemente vuelva a publicar la solución con un pequeño giro. No necesita biblioteca adicional.

Cree su propio contenedor withStylesProps .

import { withStyles } from 'material-ui/styles';

const styles = ( theme, props ) => ({
    exampleStyle: {
           color: 'red'  // <-- or try theme.palette.primary[600]
    }
})

const withStylesProps = ( styles ) =>
  Component =>
    props => {
      const Comp = withStyles(theme => styles(theme, props))(Component);
      return <Comp {...props} />;
    };

const YourComponent = ({  classes }) => 
      <Typography type="display4" className={classes.exampleStyle}>{type}</Typography>

export default withStylesProps(styles)(YourComponent);

Si no le gusta crear withStylesProps para cada componente, intente agregarlo en un archivo separado e importarlo donde desee.

@iamthuypham Gracias por el withStylesProps , la animación del componente de transición <Collapse estoy usando en algún lugar dentro del componente envuelto deja de funcionar.

@ jdolinski1 ¿Puedes copiar / pegar tu ejemplo de código?

@iamthuypham su solución tiene el inconveniente de crear una nueva etiqueta <style> cada vez que se crea un componente. Además, puede tener cuidado al usar defaultProps y agregarlos a su componente HOC'd y no a los componentes base.

image

Todo eso es compatible con react-jss , ¿no puede ser compatible de forma nativa con material-ui ?

Además, creo que el problema de @ jdolinski1 es que su código no se propaga children que puede tener el componente envuelto.

@iamthuypham Creo que no se recomienda hacer eso, como solía hacer así en el pasado, y es posible que experimente un rendimiento deficiente siempre que la aplicación crezca muy pronto. Crear una nueva instancia de component con un nuevo objeto jss style no es bueno en términos del principio de codificación porque el objeto style debe volver a renderizarse por completo, una y otra vez, cada tiempo por props cambio. Usar injectSheet de react-jss es una mejor opción. Si observa el injectSheet , verá que rompe su objeto style en 2 piezas ( static & dynamic ) por lo que solo el dynamic se vuelve a renderizar cuando props cambian.

¿Cómo usar complementos como jss-nested con injectSheet ?.

con injectSheet no puedo hacer que las declaraciones '&: hover' funcionen.
con withStyles no puedo acceder a los accesorios ...

@koutsenko Aquí hay un ejemplo:

import React from "react";
import { makeStyles } from "@material-ui/styles";
import Button from "@material-ui/core/Button";

const useStyles = makeStyles({
  root: {
    background: props => props.color,
    "&:hover": {
      background: props => props.hover
    },
    border: 0,
    borderRadius: 3,
    color: "white",
    height: 48,
    padding: "0 30px"
  }
});

export default function Hook() {
  const classes = useStyles({
    color: "red",
    hover: "blue"
  });
  return <Button className={classes.root}>Hook</Button>;
}

https://codesandbox.io/s/pw32vw2j3m

Espero que ayude.


Vaya, es asombroso el progreso que hemos logrado en ~ 1 año 😍.

ahora, ¿cómo escribes eso?

@stunaz Buena pregunta. No sé. No lo he investigado. @ eps1lon ha realizado la definición TypeScript del módulo. Puedes usarlo como punto de partida.
https://github.com/mui-org/material-ui/blob/f4281a77d15b0d6eec9d33cdc358cfb89844996d/packages/material-ui-styles/src/index.d.ts#L72

@koutsenko Aquí hay un ejemplo:

Gracias @oliviertassinari , con " react @ next " ya funciona.

@koutsenko Si no pudo hacer que jss-nested funcione, debe ser un problema de configuración en algún lugar de su codificación. Como jss-nested está incluido en jss-default-preset , entonces simplemente funciona oob

https://stackblitz.com/edit/react-py6w2v

@oliviertassinari

¿También puede configurar todo el objeto de estilos para un selector dado con accesorios? ¿A dónde se puede aplicar condicionalmente una propiedad?

Por ejemplo, así

withStyles({
    root: {
        '& > path': (props) => {
            if(props.color)
                return {
                    fill: props.color
                };
           return {};
        }
    }
})

Entonces, si el prop no existe, entonces usa el valor de relleno anterior, en lugar de otra cosa en la que tengo que configurarlo. Por ejemplo, existen otras reglas que normalmente se aplicarían al relleno, pero solo quiero establecer esta nueva propiedad de relleno si se establece color prop.

¡Gracias!

@Guardiannw Por alguna razón, su variante no funciona. Tal vez @kof podría

// 🏆
const useStyles = makeStyles({
  root: {
    "& > span": {
      backgroundColor: props => props.color || null,
    }
  }
});

// or 

const useStyles = makeStyles({
  root: props => ({
    "& > span": {
      backgroundColor: props.color || null
    }
  })
});

@oliviertassinari Estoy teniendo dificultades para conseguir que su segunda opción funcione con la función withStyles . ¿Solo funciona con makeStyles y ganchos?

@Guardiannw Está funcionando con cualquiera de las API de @material-ui/styles .

@oliviertassinari parece una sintaxis válida, se agregaron valores fn en v10, por lo que se usó v9 o necesito una reproducción de codeandbox

Ok, eso es con lo que lo probé. Puede que tenga que intentarlo de nuevo.

@oliviertassinari tengo una pregunta sobre el uso de @ materia-ui / styles, ¿está disponible y para usar en un entorno de producción ?, en la documentación indica que no funciona con la versión estable, estoy usando el " 3.9.1 ", el ejemplo https://github.com/mui-org/material-ui/issues/8726#issuecomment -452047345 que presenta tiene una característica poderosa y útil que necesito. En estos temas, vi muchos comentarios desde una perspectiva diferente y también me gusta la solución https://github.com/mui-org/material-ui/issues/8726#issuecomment -363546636 de @caub , pero tu comentario sobre su la solución es buena.

@ contrerasjf0 @material-ui/styles solo está disponible como versión alfa. Tratamos las versiones alfa como la mayoría de los paquetes del ecosistema react. Le recomendaría que nunca use ningún paquete alfa en producción. Si lo hace, debería esperar errores y cambios importantes entre cualquier versión, es decir, debería poder manejar la adición de versiones alfa de abandono.

Lo que espero es que la gente use esas versiones en proyectos de pasatiempos o en una rama separada que no se implemente en producción pero que aún se pruebe al igual que la rama de producción. Aprecio a todos los que usan esas versiones alfa y nos brindan comentarios sobre ellos.

@ up209d sí, su solución funciona, pero con
styles = { name: { cssprop: props => {} } notación, no
styles = props => ({ name: { cssprop: {} })

Además, JssProvider no es necesario.

@koutsenko

// at value level:
styles = { name: { cssprop: props => value }
styles = theme => ({ name: { cssprop: props => value })

// at class name level
styles = { name: props => ({ cssprop: value })  }
styles = theme => ({ name: props => ({ cssprop: value })  })

No puede acceder a props en el nivel superior, incluso como segundo argumento después de theme

encontre un camino

// MyComponent.tsx
import React, { PureComponent } from 'react';
import { myComponentWithStyles } from './myComponentWithStyles';

export interface MyComponentProps {
  copy: string;
  size?: number;
}

export class Twemoji extends PureComponent<myComponentWithStyles> {
  public render() {
    const { copy, classes } = this.props;

    return (
      <div className={classes.message}>
        {copy}
        <img src="https://via.placeholder.com/150" />
    </div>
    );
  }
}

// myComponentWithStyles.tsx
import React from 'react';
import { withStyles, WithStyles, Theme } from '@material-ui/core';
import { MyComponent, MyComponentProps } from './my-component';

const styles = (props: Theme & MyComponentProps) => ({
  message: {
    fontSize: props.typography.caption.fontSize,
    'box-sizing': 'content-box',
    '& img': {
      width: `${props.size || 24}px`,
      height: `${props.size || 24}px`,
      padding: '0 4px',
      verticalAlign: 'middle',
    },
  },
});

export type myComponentWithStyles = WithStyles<any>;

export const Component = (props: MyComponentProps) => {
  const StyledComponent = withStyles((theme: Theme) => styles({ ...props, ...theme }))(
    MyComponent
  );

  return <StyledComponent {...props} />;
};



md5-d0e1b51e375682cf2aad9c4d66b6c73a



<Component size={12} />

@ andreasonny83 Evite este patrón. Proporcionamos una API nativa en v4.

@oliviertassinari gracias por la actualización. ¿Ese patrón ya está disponible? ¿Alguna documentación disponible?

Una última pregunta @oliviertassinari . ¿Puedo usar makeStyles en combinación con withStyles ?

No puedo encontrar documentación para eso. Lo que estoy tratando de hacer es esto:

const useStyles = makeStyles({
  message: {
    boxSizing: 'content-box'
  }
});

export const ComponentWithStyles = withStyles(useStyles())(MyComponent);

@ andreasonny83

Use uno u otro, en su ejemplo simplemente elimine makeStyles :

const styles = { message: {boxSizing: 'content-box', background: props => props.bg} };
export const ComponentWithStyles = withStyles(styles)(MyComponent);

La gente de Gday pensó que id compartir mi solución actual con referencia a la discusión anterior, espero que ayude a alguien o alguien a ofrecer mejores consejos sobre mi solución actual. Para mi identificación de página de inicio de sesión, como una imagen de fondo aleatoria, pero aún así me gustaría mantener el poder de la API de interfaz de usuario del material. AuthPage es solo la capa de presentación principal que toma los componentes de autenticación individuales (inicio de sesión, bloqueado, contraseña olvidada, restablecimiento de contraseña, etc.) como hijos. Puede confirmar con cada actualización de página que se cargue un nuevo fondo, así como un bonito accesorio fuertemente tipado dentro de AuthPageContainer.

// AuthPage.styles.tsx

import { Container } from "@material-ui/core";
import { ContainerProps } from "@material-ui/core/Container";
import { withStyles } from "@material-ui/core/styles";
import React from "react";

interface IAuthContainerProps extends ContainerProps {
  background: string;
}

export const AuthContainer = withStyles({
  root: props => ({
    alignItems: "center",
    backgroundImage: `url(${props.background})`,
    backgroundPosition: "50% 50%",
    backgroundRepeat: "no-repeat",
    backgroundSize: "cover",
    display: "flex",
    height: "100vh",
    justifyContent: "center",
    margin: 0,
    padding: 0,
    width: "100%"
  })
})((props: IAuthContainerProps) => <Container maxWidth={false} {...props} />);

// AuthPage.tsx

import React from "react";
import forest from "../../assets/backgrounds/forest.jpg";
import sky from "../../assets/backgrounds/sky.jpg";
import uluru from "../../assets/backgrounds/uluru.jpg";
import { AuthContainer } from "./AuthPage.styles";

const AuthPage = ({ children }) => {
  const generateBackground = () => {
    const backgrounds = [forest, sky, uluru];
    const index = Math.floor(Math.random() * backgrounds.length);
    return backgrounds[index];
  };

  return (
    <AuthContainer background={generateBackground()}>{children}</AuthContainer>
  );
};

export default AuthPage;

simplemente haz algo como esto:

// styles.js
export default theme => ({
    root: props => ({
        // some styles
    }),
    ...
});

//container.js
export default withStyles(styles)(MyComponent);

¿Qué hay de pasar también el estado?

@ luky1984
No puedes. En su lugar, puede hacer:

// Component.js
<Button
    className={`
        ${classes.button} 
        ${this.state.isEnable
            ? classes.enable
            : classes.disable}
    `}
/>

O use clsx https://www.npmjs.com/package/clsx en su lugar

@caub Su solución arruina el orden de nombre de clase generado por jss.
Como está escrito aquí: https://github.com/mui-org/material-ui/issues/8726#issuecomment -363546636
He intentado usar su solución, pero su solución de componente HOC (withStylesProps) retrasa la llamada de su withStyles, porque está envuelto, por lo que llamarlo con classNames no anula el css.
Me gusta: https://codesandbox.io/s/hocs-8uhw1?file=/index.js

el fondo debe ser # 0000000 y color: azul

¿Fue útil esta página
0 / 5 - 0 calificaciones