What is the alternative of makeStyles for Material UI v.5

Viewed 22408

I just started using Material UI version 5. Originally to use my custom theme's styles, I would use makestyles, but it seems that does not work in v.5. My themes are on their own component, and to import those, I used {createTheme} instead of the old {createMuiTheme}. I have my theme imported into the Parent component as usual and have it set up as <ThemeProvider theme{theme}></ThemeProvider>.

Now, on my other component, I again was trying to use useStyles, but it was not working because it is not used in version 5. I am having a hard time trying to figure out how to convert it so that it can be used in version 5. Here is some of the unfinished code I was working on:

const useStyles = makeStyles((theme) => ({
    logo: {
        height: "8em",
        marginLeft: "0.2em",
    },
    tabContainer: {
        marginLeft: "auto",
    },
    tab: {
        ...theme.typography.tab,
        minWidth: 10,
        marginRight: "50px",
        opacity: 1,
        "&hover": {
            color: theme.palette.common.purple,
            textDecoration:"none",
        },
    },
}));

export default function Navigation(props) {
    const classes = useStyles();

    const [value, setValue] = useState(0);

    const handleChange = (e, value) => {
        setValue(value);
    };
    const refreshPage = () => {
        window.location.reload();
    };
    
    useEffect(() => {
        switch (window.location.pathname) {
            case "/":
                if (value !== 0) {
                    setValue(0);
                }
                break;
                default:
                break;
        }
    }, [value]);


    return (
      <React.Fragment>
        <ElevationScroll>
          <AppBar
            position="relative"
            style={{
              borderBottom: "2px solid black",
            }}
          >
            <Toolbar disableGutters>
                <img src={logo} alt="nasa logo" className={classes.logo}/>
                <Typography variant="h1" style={{ textAlign: "center" }}>
                  Nasa<br></br>Photos
                </Typography>
                <Tabs
                  value={value}
                  onChange={handleChange}
                  className={classes.tabContainer}
                  indicatorColor="primary"
                >
                  <Tab
                    className={classes.tab}
                    component={Link}
                    onClick={refreshPage}
                    to="/"
                    label="Home"
                  />
                </Tabs>
            </Toolbar>
          </AppBar>
        </ElevationScroll>
      </React.Fragment>
    );
}

I have read about the xs property and I have also heard of the styled() through Material UI's documentation, but I am having a hard time applying it to the code that I have written and would like a push in the right direction.

So to edit what I had earlier, I am going to also add my Theme.js file as well. I thought that this has been done correctly, but again it isn't reading my tab nor my palette.

import {createTheme} from "@mui/material/styles";

const pink = "#FFC0CB";
const lightblue = "#ADD8E6";
const purple = "#800080";
const black = "#000000";

const theme = createTheme({
    palette: {
        common: {
            pink: pink,
            lightblue: lightblue,
            purple: purple,
            black: black
        },
        primary: {
            main: pink,
            mainGradient: "linear-gradient(to left, purple, pink)",
        },
        secondary: {
            main: lightblue,
            mainGradient: "linear-gradient(to right, lightblue, pink)"
        },
    },
    typography: {
        tab: {
            fontFamily:"Orbitron",
            textTransform: "none",
            fontSize: "2.5rem",
            color: black,
        },
        h1: {
            fontFamily: "Orbitron",
            fontSize: "2.5em"
        },
        h2: {
            fontFamily: "Orbitron",
            fontSize: "2.5em"
        },
        subtitle1: {
            fontFamily: "Orbitron"
        },
        subtitle2: {
            fontFamily: "Orbitron",
            fontSize: "1.5rem"
        },
        buttons: {
            fontFamily: "Orbitron",
            textTransform: "none"
        },
    },
});

export default theme

I have imported my theme into my App.js file which is my top level file, I will include that here just in case something has been done wrong with that:

import React,{useState} from "react";
import PicOfDay from "./Components/PictureOfDay";
import Navigation from "./Components/Navigation";
import {
  Typography,
} from "@mui/material";
import {ThemeProvider} from '@mui/material/styles'
import theme from "../src/ui/Theme";
import {BrowserRouter as Router} from "react-router-dom";

function App(props) {
  const [date, setDate] = useState(new Date());
  return (
    <ThemeProvider theme={theme}>
      <Router>
        <Navigation date={date} setDate={setDate} />
        <Typography
          variant="h1"
          style={{fontSize: "5rem", textAlign: "center", marginTop:"2rem"}}
          >
            Astronomy Picture of the Day
        </Typography>  
        {/* <PicOfDay date={date} /> */}
      </Router>
    </ThemeProvider>
  );
}

export default App;

I did look at some documentation a couple of you sent me, and I was looking at the troubleshooting part where it said "[Types] Property "palette", "spacing" does not exist on type 'DefaultTheme'" because makeStyles is exported differently and it does not know about Theme. There seems to be a snipet to put in a typescript project (which I am not running, I am using javascript) and there was a section to add a ts file to my javascript and put the snippet it recommended, which I tried, but am I missing something because it did not do anything and I am not sure if I need to put something in my App.js file in order for it to read that?

4 Answers

You can still use the makeStyles utils as what you're using, but in material v5 if you love to do it you need to install one more package @mui/styles and

import { makeStyles } from '@mui/styles';

https://mui.com/guides/migration-v4/#mui-material-styles

The makeStyles JSS utility is no longer exported from @mui/material/styles. You can use @mui/styles/makeStyles instead.

Also, you need to add tab and purple to createTheme if you need them

const theme = createTheme({
  typography: {
    tab: {
      fontSize: 20,
    },
  },
  palette: {
    common: {
      purple: 'purple',
    },
  },
})

Based on documentation:

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

You can use the-sx-prop or styled

import * as React from 'react';
import { StyledEngineProvider } from '@mui/material/styles';

export default function GlobalCssPriority() {
  return (
    <StyledEngineProvider injectFirst>
      {/* Your component tree. Now you can override MUI's styles. */}
    </StyledEngineProvider>
  );
}

You need to use provider on main file to get default styles first.
Visit here Material UI injections!

so what i understood from this question is that you want to add custom classes to the material-ui components. and makestyles is giving you error about theme.. you can resolve this by providing default theme to makestyles. you can use ThemeProvider to do that.. all you've to do is create a default theme with createTheme() then use that in ThemeProvider to pass it to all components in tree below ThemeProvider.. just use ThemeProvider to wrap your root component and that will provide default theme to each makeStyles that are currently in use..

import { makeStyles } from '@mui/styles';
import { createTheme, ThemeProvider } from '@mui/material/styles';

const theme = createTheme();

 const useStyles = makeStyles((theme) => (
 root : {
   background: theme.palette.primary.main,
 }));

 function Component() {
   const classes = useStyles();
   return <div className={classes.root} />
 }

 // In the root of your app
 function App(props) {

 return <ThemeProvider theme={theme}><Component {...props} /></ThemeProvider>;
 }

Related