Material-ui: Kann withStyles Requisiten an ein Style-Objekt übergeben?

Erstellt am 17. Okt. 2017  ·  54Kommentare  ·  Quelle: mui-org/material-ui

Derzeit entwickle ich eine Komponente, die sowohl Requisiten als auch Themenobjekte erfordert.

Am Anfang funktioniert es super mit Themenobjekten

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);
....

Aber ich benötige auch Zugriff auf Requisiten im Stilobjekt.

Ich habe Beispiel versucht, aber es funktioniert nicht.

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

Am Ende kombiniere ich react-jss und withTheme , um das zu tun

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

Es funktioniert, aber ich vermisse es wirklich

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

Hilfreichster Kommentar

@oliviertassinari Es ist sehr beruhigend zu hören, dass Sie darüber

<CustomCheckbox size={16} />

Wenn wir in styles auf props zugreifen könnten, wäre dies sehr einfach:

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

oder

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

und dann:

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

export default withStyles(styles)(CustomCheckbox);

Haben Sie vorerst Empfehlungen, wie wir diese Art von Anwendungsfällen angehen sollten? Oder haben Sie Schätzungen, wann Sie möglicherweise Unterstützung für den Zugriff auf Requisiten hinzufügen können, wenn Sie withStyles verwenden?

Alle 54 Kommentare

Wir sollten das Problem wahrscheinlich beheben können, indem wir Material-UI mit dem gleichen Kontextschlüssel wie response-jss erstellen: https://github.com/cssinjs/theming/blob/master/src/channel.js#L1.
Schauen Sie sich auch #7633 an

Ich habe eine PR mit einem React-Jss-Interoperabilitätsbeispiel bereit. Ich werde das in die Dokumente einfügen. cc @kof

@oliviertassinari bedeutet die Auflösung, dass es jetzt möglich sein sollte, auf die Requisiten innerhalb der

@pelotom nein, withStyles hat keinen Zugriff auf die Eigenschaften. Aber wenn man bedenkt, wie viele Leute nach dieser Funktion fragen. Es ist etwas, das ich nach den Fehlerbehebungen priorisieren kann. Sie können das injectSheet HOC verwenden, aber es öffnet die Tür zu mehreren Problemen: Speicherleck, Hot Reloading defekt, keine classes Komposition, kein interner Ref-Zugriff, defekte Themenverschachtelung. Zumindest sind es einige der Probleme, mit denen ich in der Vergangenheit konfrontiert war und die meine Neufassung motiviert haben. Ich denke, dass diese Probleme Schritt für Schritt angegangen werden.

@oliviertassinari Es ist sehr beruhigend zu hören, dass Sie darüber

<CustomCheckbox size={16} />

Wenn wir in styles auf props zugreifen könnten, wäre dies sehr einfach:

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

oder

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

und dann:

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

export default withStyles(styles)(CustomCheckbox);

Haben Sie vorerst Empfehlungen, wie wir diese Art von Anwendungsfällen angehen sollten? Oder haben Sie Schätzungen, wann Sie möglicherweise Unterstützung für den Zugriff auf Requisiten hinzufügen können, wenn Sie withStyles verwenden?

@nmchaves Ihr Anwendungsfall scheint perfekt für den Inline-Stil-Ansatz zu FAQ
https://github.com/callemall/material-ui/blob/75a30061e76eae93c711ec202a2c7e4238a4f19a/docs/src/pages/style/SvgIcons.js#L38 -L44

Danke @oliviertassinari ! Ich hatte gehofft, dass ich dies mit withStyles , aber Inline-Stile funktionieren großartig. Und die Tatsache, dass Sie es hier + in den Dokumenten empfehlen, macht mich mit dieser Entscheidung sehr zuversichtlich. Danke noch einmal!

es wäre schön, eine prop (image src) an den style für ein backgroundImage übergeben zu können

Ich würde 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>
  )
);

Demo: https://codesandbox.io/s/k2y01rj3w7

(Ich bin überrascht ^ funktioniert ohne ThemeProvider und JssProvider https://codesandbox.io/s/q6v7krx6, ah es initialisiert es)

@caub Es funktioniert, aber Sie müssen mit diesem Muster vorsichtig sein. Das eingefügte CSS wächst mit der Anzahl der Instanzen der Komponente. Es ist ein Duplikat von #7633. Ich habe mich nicht mit dem Thema beschäftigt. Aber ich glaube, die @kof- Version verwendet eine Leistungsoptimierung.

@caub Danke fürs Teilen!

@oliviertassinari gibt es das https://github.com/cssinjs/react-jss/blob/master/readme.md#dynamic -values ​​in React -jss, ich frage mich, warum es nicht in material-ui verwendet werden konnte? Ich verstehe auch Ihren Punkt, wo Sie sagen, dass die Inline-Requisite style perfekt für dynamische Werte ist, aber es ist schöner, alle Stildefinitionen an denselben Stellen zu haben. Es gibt auch https://github.com/airbnb/react-with-styles , das className und style für effizientere dynamische Stile verarbeiten würde

ich stehe vor dem gleichen Problem kann mir jemand helfen
`React aus 'react' importieren;
Importieren von PropTypes von 'prop-types';
import { withStyles } from 'material-ui/styles';
Schublade aus 'material-ui/Drawer' importieren;
AppBar aus 'material-ui/AppBar' importieren;
Importieren Sie die Symbolleiste von 'material-ui/Toolbar';
Liste aus 'material-ui/List' importieren;
Typografie aus 'material-ui/Typography' importieren;
Importieren Sie IconButton aus 'material-ui/IconButton';
import Hidden from 'material-ui/Hidden';
Teiler aus 'material-ui/Divider' importieren;
import MenuIcon aus 'material-ui-icons/Menu';
import { mailFolderListItems, otherMailFolderListItems } from './tileData';

const Schubladenbreite = 240;

const-Stile = Thema => ({
Wurzel: {
Breite: '100%',
Höhe: 430,
marginTop: theme.spacing.unit * 3,
zIndex: 1,
Überlauf versteckt',
},
appFrame: {
Stellung: 'relativ',
Anzeige: 'flex',
Breite: '100%',
Höhe: '100%',
},
appBar: {
Stellung: 'absolut',-
RandLinks: Schubladenbreite,
[theme.breakpoints.up('md')]: {
Breite: calc(100% - ${drawerWidth}px) ,
},
},
navIconHide: {
[theme.breakpoints.up('md')]: {
Anzeige: 'keine',
},
},
Schubladenkopfzeile: theme.mixins.toolbar,
SchubladePapier: {
Breite: 250,
[theme.breakpoints.up('md')]: {
Breite: SchubladenBreite,
Stellung: 'relativ',
Höhe: '100%',
},
},
Inhalt: {
backgroundColor: theme.palette.background.default,
Breite: '100%',
Polsterung: theme.spacing.unit * 3,
Höhe: 'calc(100% - 56px)',
RandOben: 56,
[theme.breakpoints.up('sm')]: {
Höhe: 'calc(100% - 64px)',
RandOben: 64,
},
},
});

Export-Klasse ResponsiveDrawer erweitert React.Component {
Zustand = {
mobileOpen: falsch,
};

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

render() {
const { Klassen, Thema } = 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 = {
Klassen: PropTypes.object.isRequired,
Thema: PropTypes.object.isRequired,
};

Exportstandard withStyles(styles)(ResponsiveDrawer);
`

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

Das eingefügte CSS wächst mit der Anzahl der Instanzen der Komponente.

@oliviertassinari injiziertes CSS wächst +- genauso wie HTML mit Inline-Stilen wachsen würde. Statische Stile werden in separaten Blättern gerendert und in allen Komponenteninstanzen wiederverwendet.

Das hat mir gefallen, obwohl es mit einer zustandslosen Komponente das withStyle von render zu render , was wir vermeiden können, indem wir die vollständige reine Komponente verwenden.

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;

Wir können die vollständige reine Komponente verwenden, um Aktualisierungen zu vermeiden

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 Es funktioniert, aber es ist ziemlich schmerzhaft, ich werde versuchen, withStyles zu ändern, um direkter https://github.com/cssinjs/react-jss zu verwenden, das Requisiten in Werten übergeben kann

@SrikanthChebrolu könnten Sie Ihre Nachricht in ein anderes Problem verschieben, da es nicht im Thema ist?

Nur neugierig, wie der Status dazu ist? Ich habe dieses Problem, die JSS-Dokumente, die Material-UI-Dokumente durchgelesen und noch eine Lösung für Mui + Jss + TypeScript gefunden, bei der ich keine Inline-Stile verwenden muss. Das Einfügen einiger Inline-Stile ist manchmal unvermeidlich, aber in meinem Fall gibt es mehrere Stile mit vielen verschiedenen Zuständen, die sich alle auf Thema und Requisiten verlassen: enttäuscht:

@chazsolo Hey Chaz, du kannst tatsächlich injectSheet von react-jss anstelle von withStyles von mui . Auf diese Weise können Sie sowohl props als auch 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 Ich denke, Sie möchten dieser Ausgabe folgen https://github.com/cssinjs/jss/issues/682

Danke @kof und @up209d - abonniert und das Beispiel von up209d ausprobiert.

@up209d
Leider glaube ich nicht, dass das für mich funktionieren wird - ich habe implementiert, was Sie vorgeschlagen haben, und ich kann die Requisiten innerhalb des Funktionsaufrufs im styles Objekt sehen, aber ich erhalte weiterhin Fehler. Fehlen mir nur Typen? Ich erweitere WithStyles in Requisiten-Schnittstellen, damit ich Zugriff auf das classes Objekt in Requisiten habe (jetzt frage ich mich, ob dies das Problem ist, auf das in https://github.com/mui- verwiesen wird). 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'.

Mein Thema sieht so aus:

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: {
    // ...
  },
})

Das Interessante daran ist, dass arc und arcMovement gültige Eigenschaften sind, wenn ich das classes Objekt in meiner Komponente verwende:

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

Aktualisieren

Ich konnte das zum Laufen bringen, aber wie im obigen Kommentar erwähnt, musste ich alle Verweise auf WithStyles , withStyles , und ich verliere classes Komposition und Thema Verschachtelung. Ich werde es jetzt ruhen lassen und einfach die Fäden im Auge behalten. Danke für die ganze Hilfe!

@chazsolo Hey Chaz, ich bin mir nicht sicher, aber ist, dass Sie auf classes innerhalb des props des style Objekts zugreifen möchten. Wenn ja, ich denke , es ist unmöglich, da die classes nur nach jss das verarbeitete style Objekt, wie können Sie auf classes vor einem Prozess der Herstellung classes wurde nicht einmal ausgelöst?

Ich denke, @caub hat bereits eine Lösung bereitgestellt. Posten Sie einfach die Lösung mit ein wenig Drehung. Keine zusätzliche Bibliothek erforderlich.

Erstellen Sie Ihren eigenen Wrapper 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);

Wenn Sie nicht für jede Komponente withStylesProps erstellen möchten, versuchen Sie, sie in einer separaten Datei hinzuzufügen und zu importieren, wo immer Sie möchten.

@iamthuypham Danke für den Tipp. Wenn ich meine Komponente jedoch mit withStylesProps umschließe, funktioniert die Animation der Übergangskomponente <Collapse ich irgendwo innerhalb der umschlossenen Komponente verwende, nicht mehr.

@jdolinski1 Können Sie Ihr Codebeispiel kopieren/einfügen?

@iamthuypham Ihre Lösung hat den Nachteil, dass jedes Mal, wenn eine Komponente erstellt wird, ein neues <style> Tag erstellt wird. Sie können auch vorsichtig sein, wenn Sie defaultProps verwenden und sie Ihrer HOC-Komponente und nicht den Basiskomponenten hinzufügen.

image

All das wird von react-jss , kann es nicht nativ von material-ui ?

Außerdem denke ich, dass das Problem von @jdolinski1 darin besteht, dass Ihr Code children der umschlossenen Komponente möglicherweise nicht weitergibt .

@iamthuypham Ich denke, es wird nicht empfohlen, dies zu tun, wie ich es in der Vergangenheit getan habe, und Sie können die schlechte Leistung wächst . Das Erstellen einer neuen Instanz von component mit einem neuen jss style Objekt ist vom Kodierungsprinzip her nicht gut, da das style Objekt immer und immer wieder komplett neu gerendert werden muss Zeit pro props Änderung. Die Verwendung von injectSheet von react-jss ist die bessere Wahl. Wenn Sie sich das injectSheet ansehen, werden Sie feststellen, dass es Ihr style Objekt in 2 Teile zerlegt ( static & dynamic ), also nur die dynamic neu gerendert, wenn sich props ändert.

Wie verwende ich Plugins wie jss-nested mit injectSheet?.

Mit injectSheet kann ich '&:hover'-Anweisungen nicht ausführen.
Mit withStyles kann ich nicht auf Requisiten zugreifen...

@koutsenko Hier ist ein Beispiel:

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

Ich hoffe, es hilft.


Wow, es ist erstaunlich, welche Fortschritte wir in ~1 Jahr gemacht haben 😍.

wie schreibt man das jetzt?

@stunaz Gute Frage. Ich weiß nicht. Ich habe nicht hineingeschaut. @eps1lon hat die TypeScript-Definition des Moduls vorgenommen. Sie können es als Ausgangspunkt verwenden.
https://github.com/mui-org/material-ui/blob/f4281a77d15b0d6eec9d33cdc358cfb89844996d/packages/material-ui-styles/src/index.d.ts#L72

@koutsenko Hier ist ein Beispiel:

Danke @oliviertassinari , mit " react@next " funktioniert es jetzt.

@koutsenko Wenn Sie jss-nested nicht zum Laufen bringen konnten, muss dies irgendwo in Ihrer Codierung ein Konfigurationsproblem sein. Da jss-nested in jss-default-preset , funktioniert es einfach oob

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

@oliviertassinari

Können Sie auch das gesamte Stilobjekt für einen bestimmten Selektor mit Requisiten festlegen? Wo können Sie eine Immobilie bedingt beantragen?

Zum Beispiel so

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

Wenn die Requisite also nicht existiert, verwendet sie den vorherigen Füllwert und nicht etwas anderes, auf das ich sie einstellen muss? Zum Beispiel gibt es andere Regeln, die normalerweise für Fill gelten, aber ich möchte diese neue Fill-Eigenschaft nur festlegen, wenn die Requisite color ist.

Vielen Dank!

@Guardiannw Aus irgendeinem Grund funktioniert Ihre Variante nicht. Vielleicht könnte @kof unser Licht darauf bringen, warum 💡. Sie können einen der folgenden Schritte ausführen:

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

// or 

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

@oliviertassinari Es withStyles . Funktioniert es nur mit makeStyles und Hooks?

@Guardiannw Es funktioniert mit jeder der APIs von @material-ui/styles .

@oliviertassinari sieht aus wie eine gültige Syntax, fn-Werte wurden in v10 hinzugefügt, also wurde entweder v9 verwendet oder ich brauche eine Codesandbox-Reproduktion

Ok, damit habe ich es versucht. Muss es vielleicht nochmal versuchen.

@oliviertassinari Ich habe eine Frage zur Verwendung von @materia-ui/styles, ist es verfügbar und in einer Produktionsumgebung zu verwenden? In der Dokumentation wird angegeben, dass es mit der stabilen Version nicht funktioniert, ich verwende das " 3.9.1", das Beispiel https://github.com/mui-org/material-ui/issues/8726#issuecomment -452047345, das Sie präsentieren, hat eine leistungsstarke und nützliche Funktion, die ich brauche. In diesen Ausgaben habe ich viele Kommentare aus einer anderen Perspektive gesehen und auch die Lösung https://github.com/mui-org/material-ui/issues/8726#issuecomment -363546636 von @caub gefällt

@contrerasjf0 @material-ui/styles ist nur als Alpha-Version verfügbar. Wir behandeln Alpha-Versionen wie die meisten Pakete im React-Ökosystem. Ich würde empfehlen, niemals Alpha-Pakete in der Produktion zu verwenden. Wenn Sie dies tun, sollten Sie mit Bugs und Breaking Changes zwischen den Releases rechnen, dh Sie sollten in der Lage sein, mit den ablaufenden Alpha-Versionen umzugehen.

Was ich hoffe, ist, dass die Leute diese Versionen entweder in Hobbyprojekten verwenden oder sie in einem separaten Zweig verwenden, der nicht in der Produktion bereitgestellt wird, aber dennoch genau wie der Produktionszweig getestet wird. Ich schätze jeden, der diese Alpha-Versionen verwendet und uns Feedback dazu gibt.

@up209d ja, deine Lösung funktioniert, aber mit
styles = { name: { cssprop: props => {} } Notation, nicht
styles = props => ({ name: { cssprop: {} })

Außerdem ist JssProvider nicht erforderlich.

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

Sie können nicht auf props auf der obersten Ebene zugreifen, auch nicht als zweites Argument nach theme

ich habe einen Weg gefunden

// 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 Vermeiden Sie dieses Muster. Wir bieten eine native API in v4.

@oliviertassinari danke für das Update. Ist das Muster schon verfügbar? Irgendwelche Unterlagen vorhanden?

Eine letzte Frage @oliviertassinari . Kann ich makeStyles in Kombination mit withStyles ?

Ich finde keine Dokumentation dazu. Was ich versuche ist folgendes:

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

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

@andreasonny83

Verwenden Sie entweder das eine oder das andere, in Ihrem Beispiel entfernen Sie einfach makeStyles :

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

Gday-Leute dachten, ich teile meine aktuelle Lösung mit Bezug auf die obige Diskussion. Hoffentlich hilft es jemandem oder jemand kann bessere Ratschläge zu meiner aktuellen Lösung geben. Für meine Anmeldeseite ist die ID wie ein zufälliges Hintergrundbild, aber die ID möchte immer noch die Leistung der Material-UI-API beibehalten. Die AuthPage ist nur die übergeordnete Präsentationsschicht, die die einzelnen Authentifizierungskomponenten (Anmeldung, Gesperrt, Passwort vergessen, Passwort zurücksetzen usw.) als untergeordnete Elemente annimmt. Kann bei jeder Seitenaktualisierung bestätigen, dass ein neuer Hintergrund geladen wird, sowie eine schöne, stark typisierte Requisite innerhalb der AuthPageContainer-Requisite

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

mach einfach sowas:

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

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

wie sieht es mit dem Passieren auch aus?

@luky1984
Sie können nicht. Stattdessen können Sie Folgendes tun:

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

Oder verwenden Sie stattdessen clsx https://www.npmjs.com/package/clsx

@caub Ihre Lösung ruiniert die von jss generierte Klassennamenreihenfolge.
Wie hier geschrieben: https://github.com/mui-org/material-ui/issues/8726#issuecomment -363546636
Ich habe versucht, Ihre Lösung zu verwenden, aber Ihre Lösung der HOC-Komponente (withStylesProps) verzögert den Aufruf von withStyles, da sie umschlossen ist, sodass der Aufruf mit classNames die CSS nicht überschreibt.
Like: https://codesandbox.io/s/hocs-8uhw1?file=/index.js

Hintergrund sollte #0000000 sein und Farbe: blau

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen