6

I am building a 'ReactJS' application and came across the following error:

TypeError: theme.spacing is not a function
(anonymous function)
E:/Projects/PortfolioSite/React-Portfolio-Website/react-portfolio-website/src/components/Navbar.js:39
  36 |     avatar:{
  37 |         display: "block",
  38 |         margin: "0.5rem auto",
> 39 |         width: theme.spacing(13),
  40 |         heght: theme.spacing(13)
  41 |     }
  42 | }));

I have already imported makestyles from "@material-ui/styles". But it outputs the above error:

For your reference I would like to add the complete code I used:

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

import {
    AppBar,
    Toolbar,
    ListItem,
    ListItemIcon,
    IconButton,
    ListItemText,
    Avatar,
    Divider,
    List,
    Typography,
    Box
} from "@material-ui/core";

import {
    ArrowBack,
    AssignmentInd,
    Home,
    Apps,
    ContactMail

} from "@material-ui/icons";

import avatar from "../Assets/Images/avatar.png";

//CSS styles
const useStyles = makeStyles( theme =>({
    menuSliderContainer:{
        width: 250,
        background: "#511",
        height: "30rem"
    },
    avatar:{
        display: "block",
        margin: "0.5rem auto",
        width: theme.spacing(13),
        heght: theme.spacing(13)
    }
}));

const menuItems = [
    {
        listIcon: <Home/>,
        listText: "Home"
    },
    {
        listIcon: <AssignmentInd/>,
        listText: "Resume"
    },
    {
        listIcon: <Apps/>,
        listText: "Portfolio"
    },    
    {
        listIcon: <ContactMail/>,
        listText: "Contact"
    },    
    {
        listIcon: <Home/>,
        listText: "Home"
    }
]

const Navbar = () => {
    const classes = useStyles()
    return (
        <>
        <Box component="div" className={classes.menuSliderContainer}>
            <Avatar src={avatar} className={classes.avatar} alt="Pawara Siriwardhane"/>
            <Divider/>
            <List>
                {menuItems.map((lstItem,key)=>(
                    <ListItem button key={key}>
                        <ListItemIcon>
                            {lstItem.listIcon}
                        </ListItemIcon>
                        <ListItemText/>
                    </ListItem>
                ))}
            </List>
        </Box>
        <Box component="nav">
            <AppBar position="static" style={{background:"#222"}}>
                <Toolbar>
                <IconButton>
                    <ArrowBack style={{color: "tomato"}}/>
                </IconButton>
                <Typography variant="h5" style={{color:"tan"}}> Portfolio </Typography>
                </Toolbar>
            </AppBar>
        </Box>
        </>
    )
}

export default Navbar

I have already gone through the
already asked questions: Why Material-UI is not recognizing the theme.spacing function?
& the GitHub conversation: [Grid] Use a unitless spacing API #14099
but could not find a working answer.

BenMorel
  • 34,448
  • 50
  • 182
  • 322
Pawara Siriwardhane
  • 1,873
  • 10
  • 26
  • 38

3 Answers3

10

It happens because you don't have a material-ui theme defined on your application. Then apply the default material ui theme, or your own theme. It can be done in two ways:

  1. Wrap your application with ThemeProvider component
  2. Export makeStyles hook from @material-ui/core/styles instead of @material-ui/styles, in order to have the default theme.
Bar
  • 1,334
  • 1
  • 8
  • 21
8

I would like to add to previous answer pointing out that another reason for this error, once migrated from Material UI 4.xto Material 5.x and so respectively have the import from @mui/styles, assuming one has created a style object, is that indeed as in your code you are referring to the theme object that is not present anymore as default e.g:

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

export default makeStyles((theme) => ({

  paper: {
    marginTop: theme.spacing(8), // <-- this theme as isn't defined will 
                                 // cause the error
    display: 'flex',
    flexDirection: 'column',
    alignItems: 'center',
    padding: theme.spacing(2),
  },
  root: {
    '& .MuiTextField-root': {
        margin: theme.spacing(1),
  },
}

if you would like to use theme default propeties then change that style to

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

export default makeStyles(() => ({

  paper: {
    marginTop: useTheme().spacing(8),
    display: 'flex',
    flexDirection: 'column',
    alignItems: 'center',
    padding: useTheme().spacing(2),
  },
  root: {
    '& .MuiTextField-root': {
    margin: useTheme().spacing(1),
  },
},
BenMorel
  • 34,448
  • 50
  • 182
  • 322
Carmine Tambascia
  • 1,628
  • 2
  • 18
  • 32
3

According to the latest version of MUI, you should import makeStyles from @mui/styles.

  1. Add a ThemeProvider at the root of your application since the defaultTheme is no longer available.
  2. If you are using this utility together with @mui/material, it's recommended that you use the ThemeProvider component from @mui/material/styles
Kisore
  • 59
  • 5
  • Isn't makeStyles deprecated in mui v5? Could not use @mui/styles. – user2078023 Feb 22 '22 at 09:32
  • Yes, @user2078023 @mui/styles become the legacy styling solution. Docs says " @mui/styles is the legacy styling solution for MUI. It depends on JSS as a styling solution, which is not used in the @mui/material anymore, deprecated in v5. If you don't want to have both emotion & JSS in your bundle, please refer to the @mui/system documentation which is the recommended alternative." Thanks! – Kisore Feb 25 '22 at 08:44