Material UI - makeStyles - Cannot read properties of undefined
Asked Answered
S

4

5

I'm studying Material UI, and in the course, the instructor asks me to style just one component and not the entire theme.

For that, it uses the makeStyles function and spreads the theme.mixins.toolbar. The problem is when I do this, I have the following error:

TypeError: Cannot read properties of undefined (reading 'toolbar')

This course is apparently in version 4, and I am using version 5. Despite this, my code appears to follow the changes that the documentations asks for. So what could be causing this error?

app.js

import "./App.css";
import Header from "./components/ui/Header";
import { ThemeProvider } from "@material-ui/core/styles";
import theme from "./components/ui/Theme";

function App() {
    return (
        <ThemeProvider theme={theme}>
            <Header />
        </ThemeProvider>
    );
}

export default App;

Theme.js

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

const arcBlue = "#0B72B9";
const arcOrange = "#FFBA60";

export default createTheme({
    typography: {
        h3: {
            fontWeight: 100,
        },
    },
    palette: {
        common: {
            blue: `${arcBlue}`,
            orange: `${arcOrange}`,
        },
        primary: {
            main: `${arcBlue}`,
        },
        secondary: {
            main: `${arcOrange}`,
        },
    },
});

header/index.jsx

import React from "react";
import AppBar from "@mui/material/AppBar";
import Toolbar from "@mui/material/Toolbar";
import useScrollTrigger from "@mui/material/useScrollTrigger";
import Typography from "@mui/material/Typography";
import { makeStyles } from "@material-ui/styles";

function ElevationScroll(props) {
    const { children, window } = props;
    const trigger = useScrollTrigger({
        disableHysteresis: true,
        threshold: 0,
        target: window ? window() : undefined,
    });

    return React.cloneElement(children, {
        elevation: trigger ? 10 : 0,
    });
}

const useStyles = makeStyles((theme) => ({
    toolbarMargin: { ...theme.mixins.toolbar },
}));

function Header() {
    const classes = useStyles();
    return (
        <React.Fragment>
            <ElevationScroll>
                <AppBar color="primary">
                    <Toolbar>
                        <Typography variant="h3" component="h3">
                            Nome de teste
                        </Typography>
                    </Toolbar>
                </AppBar>
            </ElevationScroll>
            <div className={classes.toolBarMargin} />
        </React.Fragment>
    );
}

export default Header;

Simferopol answered 12/10, 2021 at 22:40 Comment(1)
I'm a bit confused. Didn't you just answer yourself recently?Paramount
P
5

Since you're using v5, change your ThemeProvider, createTheme and makeStyles import path from:

import { ThemeProvider, createTheme, makeStyles } from "@material-ui/core/styles";

To:

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

@material-ui/core is v4 package and @mui/material is the v5 equivalent. The API from the 2 versions are not compatible. In v5, makeStyles is also moved to a legacy package called @mui/styles, if you are using MUI v5 in a new project, you should switch completely to styled/sx API as recommended by the MUI team.

Related answers

Paramount answered 13/10, 2021 at 5:17 Comment(2)
In addition to the changes mentioned, I needed to make three more things to work. npm install @mui/styles, then import { makeStyles } from "@mui/styles";````, and I also called the object classes using the correct propety, with b in lowercase. From: <div className={classes.toolBarMargin} />``` to <div className={classes.toolbarMargin} />Simferopol
@MaximilianKaden If you're creating a new project. You should drop makeStyles usage and switch to styled/sx instead. It's the recommended API in v5 whereas makeStyles is a legacy one and might be remove in future verions of MUI.Paramount
P
4

I faced similar issue with Can not read properties of undefined, reading refs thrown by makeStyles. In my case it was mui v5 and the issue occurred after upgrading to React 18.

In my case it turned out I had some legacy makeStyles(()=>createStyles) wrapped in a manner:

const useStyles = (minWidth: number) =>
  makeStyles((theme: Theme) => ...

I had to change it to:

const useStyles =
  makeStyles((theme: Theme) => ...

Perhaps it will be useful for somebody else facing the issue.

Pruinose answered 23/8, 2022 at 12:22 Comment(3)
Hey @Pruinose I am facing exactly same issue after upgrading to React 18 but I am already having the makeStyles in specified way: import { makeStyles } from '@mui/styles'; const useStyles = makeStyles((theme) => ({ root: { flexGrow: 1, minWidth: '100px', }, }));Vacant
From what I checked it turns out everywhere I am using it with createStyles: import createStyles from "@mui/styles/createStyles"; import { makeStyles } from "@mui/styles"; const useStyles = makeStyles((theme: Theme) => createStyles({ root: { flexGrow: 1, minWidth: '100px', }, })); - maybe try this approach? If I remember correctly createStyles is a type wrapper for style object.Pruinose
I got above error in a component where makeStyles was called directly as const classes = makeStyles(...)()...Whelk
T
2

I created a project on CodeSandbox and it doesn't seem the problem in code. I guess you need to check the version of package you installed in package.json file.

Here is the link to the CodeSandbox project and you can see the console.log message on console tab.

https://codesandbox.io/s/check-makestyle-eq67m?file=/src/components/ui/Header/index.js

Tatter answered 13/10, 2021 at 4:6 Comment(3)
Hi @jihyun lee. Using version 4 of Material UI actually works. Your example code uses the "@material-ui/core" version: "4.12.3". But the updated version (That I'm using), is "@material-ui/core": "^5.0.0-beta.5".Simferopol
Opps. My bad. should've checked the version. Like the NearHuscarl's answer, you need to change the module name from @material-ui/core/styles to @mui/material/styles. I changed the the example code and it works!Tatter
Yeah, also need to import { makeStyles } from "@mui/styles"; instead of @material-ui/styles;. This is not noted in the new documentation by the way. Thank you for your help !Simferopol
S
0

Solution

Install @mui/styles

npm install @mui/styles

Change

import { ThemeProvider, createTheme } from "@material-ui/core/styles";

To

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

And

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

To

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

And

<div className={classes.toolBarMargin} />

To

<div className={classes.toolbarMargin} />

Simferopol answered 14/10, 2021 at 6:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.