Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to style components using makeStyles and still have lifecycle methods in Material UI?

People also ask

Can you use material UI with styled-components?

By default, MUI components come with Emotion as their style engine. If, however, you would like to use styled-components , you can configure your app by following the styled engine guide or starting with one of the example projects: Create React App with styled-components.

Is makeStyles deprecated?

It is deprecated in v5. It depends on JSS as a styling solution, which is not used in the @mui/material anymore.


Hi instead of using hook API, you should use Higher-order component API as mentioned here

I'll modify the example in the documentation to suit your need for class component

import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '@material-ui/styles';
import Button from '@material-ui/core/Button';

const styles = theme => ({
  root: {
    background: 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)',
    border: 0,
    borderRadius: 3,
    boxShadow: '0 3px 5px 2px rgba(255, 105, 135, .3)',
    color: 'white',
    height: 48,
    padding: '0 30px',
  },
});

class HigherOrderComponentUsageExample extends React.Component {
  
  render(){
    const { classes } = this.props;
    return (
      <Button className={classes.root}>This component is passed to an HOC</Button>
      );
  }
}

HigherOrderComponentUsageExample.propTypes = {
  classes: PropTypes.object.isRequired,
};

export default withStyles(styles)(HigherOrderComponentUsageExample);

I used withStyles instead of makeStyle

EX :

import { withStyles } from '@material-ui/core/styles';
import React, {Component} from "react";

const useStyles = theme => ({
        root: {
           flexGrow: 1,
         },
  });

class App extends Component {
       render() {
                const { classes } = this.props;
                return(
                    <div className={classes.root}>
                       Test
                </div>
                )
          }
} 

export default withStyles(useStyles)(App)

What we ended up doing is stopped using the class components and created Functional Components, using useEffect() from the Hooks API for lifecycle methods. This allows you to still use makeStyles() with Lifecycle Methods without adding the complication of making Higher-Order Components. Which is much simpler.

Example:

import React, { useEffect, useState } from 'react';
import axios from 'axios';
import { Redirect } from 'react-router-dom';

import { Container, makeStyles } from '@material-ui/core';

import LogoButtonCard from '../molecules/Cards/LogoButtonCard';

const useStyles = makeStyles(theme => ({
  root: {
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
    margin: theme.spacing(1)
  },
  highlight: {
    backgroundColor: 'red',
  }
}));

// Highlight is a bool
const Welcome = ({highlight}) => { 
  const [userName, setUserName] = useState('');
  const [isAuthenticated, setIsAuthenticated] = useState(true);
  const classes = useStyles();

  useEffect(() => {
    axios.get('example.com/api/username/12')
         .then(res => setUserName(res.userName));
  }, []);

  if (!isAuthenticated()) {
    return <Redirect to="/" />;
  }
  return (
    <Container maxWidth={false} className={highlight ? classes.highlight : classes.root}>
      <LogoButtonCard
        buttonText="Enter"
        headerText={isAuthenticated && `Welcome, ${userName}`}
        buttonAction={login}
      />
   </Container>
   );
  }
}

export default Welcome;

useStyles is a React hook which are meant to be used in functional components and can not be used in class components.

From React:

Hooks let you use state and other React features without writing a class.

Also you should call useStyles hook inside your function like;

function Welcome() {
  const classes = useStyles();
...

If you want to use hooks, here is your brief class component changed into functional component;

import React from "react";
import { Container, makeStyles } from "@material-ui/core";

const useStyles = makeStyles({
  root: {
    background: "linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)",
    border: 0,
    borderRadius: 3,
    boxShadow: "0 3px 5px 2px rgba(255, 105, 135, .3)",
    color: "white",
    height: 48,
    padding: "0 30px"
  }
});

function Welcome() {
  const classes = useStyles();
  return (
    <Container className={classes.root}>
      <h1>Welcome</h1>
    </Container>
  );
}

export default Welcome;

🏓 on ↓ CodeSandBox ↓

Edit React hooks