Material-ui: theme.spacing is not a function with @material-ui/[styles/core] 4.0.1

Created on 31 May 2019  ·  18Comments  ·  Source: mui-org/material-ui

Trying to fix another issue today I tried to reset my whole Material-UI 4.0.0 workspace, migrating both core and style to latest 4.0.1

As soon as I try to use a ThemeProvider I get TypeError theme.spacing is not a function.

  • [x] This is not a v0.x issue.
  • [x] I have searched the issues of this repository and believe that this is not a duplicate. Well... not exactly... I found a duplicate at https://github.com/mui-org/material-ui/issues/15834 but the fix seems not working, it's like the bad usage is in the core

Expected Behavior 🤔

Just want to see the theming working. I'm confused by the fact that theme.spacing seems used by both master and next branches, so this seems the way to go.

Current Behavior 😯

See error above

Steps to Reproduce 🕹

Link: https://codesandbox.io/s/materialui-style-issue-rk8n0

Context 🔦

I started a whole new application and I'm trying to clue together all of the style feature of Material-UI. That said, before the migration to 4.0.1 of style module I had not such issues, so I'm unsure if 4.x releases are someway unstable or what.

Your Environment 🌎

| Tech | Version |
|--------------|---------|
| Material-UI | v4.0.1 |
| React | 16.0.6 |
| Browser | FF/Chrome latest |
| TypeScript | - |

question

Most helpful comment

Sorry I found the problem.
I change import { withStyles } from '@material-ui/styles'; to import { withStyles } from '@material-ui/core/styles'; and everything works fine.
Thanks!

All 18 comments

@keul Be aware of the difference between core and styles: https://material-ui.com/customization/default-theme/#material-ui-core-styles-vs-material-ui-styles.

Thanks @oliviertassinari.

Material-UI styles are powered by the @material-ui/styles npm package. It's a styling solution for React. This solution is isolated, it has has no knowledge of the default Material-UI theme. To remove the need for injecting a theme in the React's context systematically, we are wrapping the style modules (makeStyles, withStyles and styled) with the default Material-UI theme

To be honest I don't get the point here, nor how this is related to the issue. This means than I don't need the ThemeProvider because already shipped when importing from core/styles?

Just to give additional context: my code was working using core 4.0.0 and styles 3.0.0-alpha.10
I started having issue this morning, after migrating to 4.0.1

I can quickly go back to old package-lock version, but I'd like to get the big picture

@keul Alright, maybe the following will be clearer. You are injecting a new theme that is not compatible with the core components. You should use createMuiTheme.

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

const theme = createMuiTheme({
  spacing: 4,
  palette: {
    primary: {
      main: "#007bff",
    },
  }
});

@oliviertassinari well... thanks. This fixed the issue.

I'm pretty sure I copied this raw code from the documentation, it's the same way-to-go I find at https://material-ui.com/styles/advanced/. As a new user (last time I used MUI it was version 0.x) this is not really clear but I probably have to give it some time.

Sorry for the noise!

Anything in https://material-ui.com/styles/x is Material Design unrelated. It's a styling solution for React.

Sorry, I still can't understand.
Can we send theme as a argument to styles, and wrap it by withstyles? Like the following.

const styles = theme => {({
    root: {
      // JSS uses px as the default units for this CSS property.
      padding: theme.spacing(2), // = 8 * 2
    },
})};

Can we send theme as a argument to styles, and wrap it by withstyles? Like the following.

@ByronHsu Yes, if you import from @material-ui/core/styles or if you inject a theme created with createMuiTheme().

But it return theme.spacing is not a function.

@ByronHsu Do you have a reproduction?

Sorry I found the problem.
I change import { withStyles } from '@material-ui/styles'; to import { withStyles } from '@material-ui/core/styles'; and everything works fine.
Thanks!

I'm having this issue as well and I'm using

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

const useStyles = makeStyles((theme: Theme) => ({
  icon: {
    marginRight: theme.spacing(1)
  }
}));

This component is wrapped in a <ThemeProvider />

Same issue occurs if I instead use:

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

const useStyles = makeStyles((theme: Theme) => ({
  icon: {
    marginRight: theme.spacing(1)
  }
}));

I get:

TypeError: theme.spacing is not a function

All MUI packages are up to date, master branch.

Nevermind, rookie mistake. I forgot to wrap my new theme in createMuiTheme - I was returning a basic object instead.

same here

I see this issue if I do everything as expected, except code for an outer theme when there isn't one. For example:

breaks:

<MuiThemeProvider theme={outer => ({...outer, ...theme})}>...</MuiThemeProvider>

works:

<MuiThemeProvider>
  <MuiThemeProvider theme={outer => ({...outer, ...theme})}>...</MuiThemeProvider>
</MuiThemeProvider>

I see there is a warning for this case. It seems like it should still work, though, or at least leave that logic to the provided function.

go from
marginRight: theme.spacing(1)

change it to
marginRight: theme.spacing.unit

This is also an issue for me. It seems to be a type error, because the I'm logging the value itself and it's working, but next.js throws an error saying it doesn't exist. Breakpoints too.

Sorry I found the problem.
I change import { withStyles } from '@material-ui/styles'; to import { withStyles } from '@material-ui/core/styles'; and everything works fine.
Thanks!

Thank you @ByronHsu

its working

Was this page helpful?
0 / 5 - 0 ratings

Related issues

revskill10 picture revskill10  ·  3Comments

chris-hinds picture chris-hinds  ·  3Comments

mb-copart picture mb-copart  ·  3Comments

TimoRuetten picture TimoRuetten  ·  3Comments

anthony-dandrea picture anthony-dandrea  ·  3Comments