How to use useStyle to style Class Component in Material Ui

JavascriptReactjsMaterial UiReact HooksReact Component

Javascript Problem Overview


I want to use useStyle to style the Class Component . But this can be easily done hooks. but i want to use Component instead. But I cant figure out how to do this.

import React,{Component} from 'react';
import Avatar from '@material-ui/core/Avatar';
import { makeStyles } from '@material-ui/core/styles';
import LockOutlinedIcon from '@material-ui/icons/LockOutlined';


    const useStyles = makeStyles(theme => ({
      '@global': {
        body: {
          backgroundColor: theme.palette.common.white,
        },
      },
      paper: {
        marginTop: theme.spacing(8),
        display: 'flex',
        flexDirection: 'column',
        alignItems: 'center',
      },
      avatar: {
        margin: theme.spacing(1),
        backgroundColor: theme.palette.secondary.main,
      }
}));

class SignIn extends Component{
  const classes = useStyle(); // how to assign UseStyle
  render(){
     return(
    <div className={classes.paper}>
    <Avatar className={classes.avatar}>
      <LockOutlinedIcon />
    </Avatar>
    </div>
  }
}
export default SignIn;

Javascript Solutions


Solution 1 - Javascript

You can do it like this:

import { withStyles } from "@material-ui/core/styles";

const styles = theme => ({
  root: {
    backgroundColor: "red"
  }
});

class ClassComponent extends Component {
  state = {
    searchNodes: ""
  };

  render() {
    const { classes } = this.props;
    return (
      <div className={classes.root}>Hello!</div>
    );
  }
}

export default withStyles(styles, { withTheme: true })(ClassComponent);

Just ignore the withTheme: true if you aren't using a theme.


To get this working in TypeScript, a few changes are needed:

import { createStyles, withStyles, WithStyles } from "@material-ui/core/styles";

const styles = theme => createStyles({
  root: {
    backgroundColor: "red"
  }
});

interface Props extends WithStyles<typeof styles>{ }

class ClassComponent extends Component<Props> {

// the rest of the code stays the same

Solution 2 - Javascript

for class Components you can use withStyles instead of makeStyles

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

const useStyles = theme => ({
fab: {
  position: 'fixed',
  bottom: theme.spacing(2),
  right: theme.spacing(2),
},
  });

class ClassComponent extends Component {
   render() {
            const { classes } = this.props;

            {/** your UI components... */}
      }
} 


export default withStyles(useStyles)(ClassComponent)

Solution 3 - Javascript

Hey I had a similar problem. I solved it by replacing makeStyles with withStyles and then at the point where do something like const classes = useStyle();, replace that with const classes = useStyle;

You notice useStyle is not supposed to be a function call but rather a variable assignment.

That should work fine after you've made those changes.

Solution 4 - Javascript

useStyles is a react hook. You can use it in function component only.

This line creates the hook:

const useStyles = makeStyles(theme => ({ /* ... */ });

You are using it inside the function component to create classes object:

const classes = useStyles();

Then in jsx you use classes:

<div className={classes.paper}>

Suggested resources: https://material-ui.com/styles/basics/ https://reactjs.org/docs/hooks-intro.html

Solution 5 - Javascript

Like other answers already stated you should use withStyles to augment a component and pass the classes through the properties. I've taken the liberty to modify the Material-UI stress test example into a variant that uses a class component.

Note that the withTheme: true option is normally not needed when you simply want to use the styles. It is needed in this example because the actual value of the theme is used in the render. Setting this option makes theme available through the class properties. The classes prop should always be provided, even if this option is not set.

const useStyles = MaterialUI.withStyles((theme) => ({
  root: (props) => ({
    backgroundColor: props.backgroundColor,
    color: theme.color,
  }),
}), {withTheme: true});

const Component = useStyles(class extends React.Component {
  rendered = 0;

  render() {
    const {classes, theme, backgroundColor} = this.props;
    return (
      <div className={classes.root}>
        rendered {++this.rendered} times
        <br />
        color: {theme.color}
        <br />
        backgroundColor: {backgroundColor}
      </div>
    );
  }
});

function StressTest() {
  const [color, setColor] = React.useState('#8824bb');
  const [backgroundColor, setBackgroundColor] = React.useState('#eae2ad');

  const theme = React.useMemo(() => ({ color }), [color]);
  const valueTo = setter => event => setter(event.target.value);

  return (
    <MaterialUI.ThemeProvider theme={theme}>
      <div>
        <fieldset>
          <div>
            <label htmlFor="color">theme color: </label>
            <input
              id="color"
              type="color"
              onChange={valueTo(setColor)}
              value={color}
            />
          </div>
          <div>
            <label htmlFor="background-color">background-color property: </label>
            <input
              id="background-color"
              type="color"
              onChange={valueTo(setBackgroundColor)}
              value={backgroundColor}
            />
          </div>
        </fieldset>
        <Component backgroundColor={backgroundColor} />
      </div>
    </MaterialUI.ThemeProvider>
  );
}

ReactDOM.render(<StressTest />, document.querySelector("#root"));

<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" />
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons" />
<script src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/@material-ui/core@4/umd/material-ui.production.min.js"></script>
<div id="root"></div>

Solution 6 - Javascript

Yet another way to do this, albeit a bit of a workaround.

Some may say this doesn't really answer the question, but I would argue that it does. The end result is useStyles() delivers the styling for a class-based yet multi-part parent component.

In my case I needed a standard Javascript class export so that I could call new MyClass() without a MyClass is not a constructor error.

import { Component } from "./react";
import { makeStyles } from "@material-ui/core/styles";

const useStyles = makeStyles((theme) => ({
  someClassName: {
    ...
  }
}));

export default class MyComponent extends Component {
  render() {
    return <RenderComponent {...this.props} />;
  }
}

function RenderComponent(props) {
  const classes = useStyles();

  return (
    /* JSX here */
  );
}

Solution 7 - Javascript

how to add multiple classes in ClassName with class component

import { withStyles } from "@material-ui/core/styles";

const styles = theme => ({
  root: {
    backgroundColor: "red"
  },
  label: {
    backGroundColor:"blue"
 }
});

class ClassComponent extends Component {
  state = {
    searchNodes: ""
  };

  render() {
    const { classes } = this.props;//   
    return (
      <div className={classes.root + classes.label}>Hello!</div> //i want to add label style also with
    );
  }
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJamith NImanthaView Question on Stackoverflow
Solution 1 - JavascriptVicenteView Answer on Stackoverflow
Solution 2 - JavascriptessayoubView Answer on Stackoverflow
Solution 3 - JavascriptBarnabasView Answer on Stackoverflow
Solution 4 - JavascriptKaniaView Answer on Stackoverflow
Solution 5 - Javascript3limin4t0rView Answer on Stackoverflow
Solution 6 - JavascriptkentrView Answer on Stackoverflow
Solution 7 - Javascriptiamaksingh11View Answer on Stackoverflow