Theme not being provided to sub-components using makeStyles MUI v5 [duplicate] - reactjs

I'm studying MUI, 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;

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
Difference between #mui/material/styles and #mui/styles?
Cannot use palette colors from MUI theme
MUI createTheme is not properly passing theme to MUI components

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

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.

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} />

Related

React Material UI Theme provider doesn't change colors version 5x

I'm building an app in NextJs that must support custom themes. By reading the Material UI documentation to change the primary color something like should work:
import { ThemeProvider, createTheme } from '#emotion/react';
import { Button } from '#mui/material';
const theme = createTheme({
pallete: {
primary: #fefefe,
}
});
export default (_) => (
<ThemeProvider theme={theme}>
<Button>Primary</Button>
</ThemeProvider>
);
However the color of the button never changes, I'm I doing anything wrong?
You have to use ThemeProvider from #mui package, not from #emotion.
use - import { createTheme, ThemeProvider } from '#mui/material'

MUI5 :Cannot read properties of undefined (reading 'primary')

I am using MUI5 with reactjs and I wanted to use the makeStyles to add some custom CSS to the MUI components but its not allowing me to use the default theme inside the makestyles so my code is :
import { Grid, Card, CardContent,Typography, CardActions,Button, AppBar, Toolbar,
Box,IconButton, Menu, MenuItem, InputBase, alpha, styled, Badge, Container, CardHeader,
CardMedia } from '#mui/material';
import EmailIcon from '#mui/icons-material/Email';
import NotificationsIcon from '#mui/icons-material/Notifications';
import React from 'react'
import { makeStyles } from '#mui/styles'
const useStyles = makeStyles((theme) => ({
root: ({
backgroundColor: theme.palette.primary.light,
color: theme.color,
}),
}));
const App = () => {
const classes = useStyles();
return(
<Fragment>
<Container className={classes.root}>
<Typography>
this is a very random text to fill
</Typography>
</Container>
</Fragment>
)
}
export default App;
its not allowing me to get to the theme props inside the makestyles
First of all, try assigning "root" as a normal object property like this-
const useStyles = makeStyles((theme) => ({
root: {
backgroundColor: theme.palette.primary.light,
color: theme.color,
}
}));
If it does not work, you may want to take a look at this-
https://mui.com/styles/basics/#using-the-theme-context

Why is the custom palette ignored in MUI?

Using MUI 4.12 and I have set the type to dark and used CssBaseline which was the solution I have seen for other answers but still it seems the type is completely ignored.
import {React, Fragment} from 'react'
import {
createTheme,
ThemeProvider,
makeStyles,
Zoom,
Fab,
useScrollTrigger,
Box,
CircularProgress
} from "#material-ui/core";
import CssBaseline from '#mui/material/CssBaseline';
import KeyboardArrowUpIcon from "#material-ui/icons/KeyboardArrowUp";
import "./App.css";
import Footer from "./Components/Footer/footer";
import { AppRouter } from "./Router/Router";
const theme = createTheme({
palette: {
type: "dark",
primary: {
main: "#d32f2f",
},
secondary: {
main: "#ef5350",
},
inherit: {
main: "white",
},
},
overrides : {
MuiTab : {
textColorInherit : {
opacity :1,
}
}
}
});
function App(props) {
return (
<Fragment>
<div className="App">
<Box id="back-to-top-anchor" />
<ThemeProvider theme={theme}>
<CssBaseline/>
<AppRouter />
<ScrollTop {...props}>
<Fab color="primary" size="small" aria-label="scroll back to top">
<KeyboardArrowUpIcon />
</Fab>
</ScrollTop>
</ThemeProvider>
</div>
<Footer />
</Fragment>
);
}
You're importing CssBaseline from #mui/material which is the package for MUI v5. In v5, MUI uses emotion instead of JSS (different style library internally), so your code doesn't work. You need to import the components from the same version to fix the problem:
V5
import { createTheme, ThemeProvider, CssBaseline, ... } from '#mui/material';
V4
import { createTheme, ThemeProvider, CssBaseline, ... } from '#material-ui/core';
Related answer
Material UI Dark Mode

ThemeProvider does not apply theme to child components from material ui library

I am using Typescript, React. Material-UI (now MUI) and Webpack.
I am trying to apply a theme using material-ui's ThemeProvider but it only seems to apply that theme to components that are not from the material-ui library.
import React from 'react'
import { ThemeProvider, CssBaseline } from '#material-ui/core'
import { createTheme } from '#material-ui/core/styles'
import Router from './components/Router'
import NavBar from './components/NavBar'
import Toolbar from '#mui/material/Toolbar'
import Container from '#mui/material/Container'
export function App(): JSX.Element {
const theme = createTheme({
palette: {
type: 'dark',
primary: {
main: '#ffeb3b',
},
secondary: {
main: '#795548',
},
},
})
return (
<ThemeProvider theme={theme}>
<NavBar />
<Toolbar />
<Container>
<Router />
</Container>
<CssBaseline />
</ThemeProvider>
)
}
The I can see darkmode being toggled so long as the backdrop for the app is not a MUI paper element. Also my AppBar contained within my NavBar component does not change color when I change the palette main colors.
Putting the theme into a different file does not help. And I have already run Yarn upgrade so everything should be up to date. What is going on?

Change primary and secondary colors in MUI

I have a react app using MUI. When you import a button, you can set its style using primary={true} or secondary={true}. I want to change the primary and secondary colors. I found out that I can do that this way:
const theme = createMuiTheme({
palette: {
primary: '#00bcd4',
secondary: '#ff4081'
}
});
and then here I can use it:
<MuiThemeProvider theme={theme}>
<App/>
</MuiThemeProvider>
But I got an error: createMuiTheme is not a function...
I went into the MUI package and found out that there is not such file and when I import createMuiTheme, I get undefined. It's supposed to be imported from material-ui/styles/theme but it actually doesn't have this folder at all!
I was using material-ui#0.19.4. I updated this package to v20 and there is still no such folder anyway.
New Answer
With the latest version of Material UI, createMuiTheme is deprecated now. Hence, instead of that we should use createTheme
import React from 'react';
import { render } from 'react-dom';
import { MuiThemeProvider, createTheme } from '#material-ui/core/styles';
import Root from './Root';
// use default theme
// const theme = createTheme();
// Or Create your Own theme:
const theme = createTheme({
palette: {
secondary: {
main: '#E33E7F'
}
}
});
function App() {
return (
<MuiThemeProvider theme={theme}>
<Root />
</MuiThemeProvider>
);
}
render(<App />, document.querySelector('#app'));
Old answer
From https://material-ui.com/customization/themes/:
import React from 'react';
import { render } from 'react-dom';
import { MuiThemeProvider, createMuiTheme } from '#material-ui/core/styles';
import Root from './Root';
// use default theme
// const theme = createMuiTheme();
// Or Create your Own theme:
const theme = createMuiTheme({
palette: {
secondary: {
main: '#E33E7F'
}
}
});
function App() {
return (
<MuiThemeProvider theme={theme}>
<Root />
</MuiThemeProvider>
);
}
render(<App />, document.querySelector('#app'));
The two diferrences with the documentation i noticed is the name of the prop for the MuiThemeProvider:
<MuiThemeProvider muiTheme={muiTheme}>
<AppBar title="My AppBar" />
</MuiThemeProvider>
And the function is not createMuiTheme but getMuiTheme:
import getMuiTheme from 'material-ui/styles/getMuiTheme';
Update:
If you open the light theme from the package, they are not using primary or secondary, maybe you should try like that?
You should be using v1-beta as the docs recommend. I had these issues myself and realised that I was using an outdated version of MUI.
npm install material-ui#next
Import:
import { MuiThemeProvider, createMuiTheme } from 'material-ui/styles';
Create your theme:
const theme = createMuiTheme({
palette: {
secondary: {
main: '#d32f2f'
}
},
});
Apply it to your button:
<MuiThemeProvider theme={theme}>
<Button
onClick={this.someMethod}
variant="raised"
color="secondary"
</Button>
</MuiThemeProvider>
Usually if you get any import issues regarding MUI, then it's almost every time some version problem.
If you want to use a custom color, put it in the main property of an object. MUI will use that color to calculate the dark, light and contrastText values besides the main one.
dark, light: a darker and lighter versions of the main color.
contrastText: the color of the text if the background color is the main color.
The example below:
const theme = createTheme({
palette: {
primary: {
main: '#ff0000', // very red
},
secondary: {
main: '#00fff0', // very cyan
},
},
});
Generates the following color properties in the primary and secondary object:
const theme = useTheme();
const { main, dark, light, contrastText } = theme.palette.primary;
// same with secondary
// const { main, dark, light, contrastText } = theme.palette.secondary;
You can also use MUI colors by passing the color object directly to primary or secondary property. This time, MUI uses the property 500 (for example amber[500]) to calculate 3 other colors. The code below:
import { amber, deepPurple } from '#mui/material/colors';
const theme = createTheme({
palette: {
primary: amber,
secondary: deepPurple,
},
});
Generates the following color properties in the primary and secondary object, Note that because you pass the whole color, all other shades from 50 to A700 are also available as a small side-effect:
Live Demo
Related Answers
How to add custom MUI palette colors
Material-UI: how to access all palette shades inside component
The new API for MUI Material v5 is described in https://mui.com/material-ui/customization/theming/.
import * as React from 'react';
import { red } from '#mui/material/colors';
import { ThemeProvider, createTheme } from '#mui/material/styles';
const theme = createTheme({
palette: {
primary: {
main: red[500],
},
},
});
const App = () =>
<ThemeProvider theme={theme}>...</ThemeProvider>;

Resources