What Is the Benefit of Using Withstyles Over Makestyles

What is the benefit of using withStyles over makeStyles?

UPDATE This question/answer is geared towards v4 of Material-UI. I have added some v5 info/links at the end.


The Hook API (makeStyles/useStyles) can only be used with function components.

The Higher-order component API (withStyles) can be used with either class components or function components.

They both provide the same functionality and there is no difference in the styles parameter for withStyles and makeStyles.

If you are using it with a function component, then I would recommend using the Hook API (makeStyles). withStyles has a little bit of extra overhead compared to makeStyles (and internally delegates to makeStyles).

If you are customizing the styles of a Material-UI component, using withStyles is preferable to wrapping it with your own component solely for the purpose of calling makeStyles/useStyles since then you would just be re-implementing withStyles.

So wrapping a Material-UI component might look like the following example (from How to style Material-UI's tooltip?):

const BlueOnGreenTooltip = withStyles({
tooltip: {
color: "lightblue",
backgroundColor: "green"
}
})(Tooltip);

Edit Tooltip customization


For v5 of Material-UI, styled replaces withStyles and makeStyles. How to style Material-UI's tooltip? contains v5 examples. I also have further discussion of v5 styling options in Using conditional styles in Material-UI with styled vs JSS.

What is difference between withStyles and makeStyles from Material UI framework?

The main difference is that makeStyle/useStyle is being used at function components as a hook, and withStyles is an higher order component.

useStyle and withStyles provide the same functionality and take the same style object params.

you should use withStyles when you develop apps with React version that doens't support hooks yet, or when you style a class-based component.

Material-UI makeStyles vs withStyles generated class names

The second (optional) argument to makeStyles is an object of options to control the behavior of makeStyles. One of the options is a name which is then used as a prefix for the class names. withStyles passes Component.displayName as the name option. You can specify whatever name you want in order to control the class name prefix, for instance in my example below the class name ends up being Hello-root-1.

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

const useStyles = makeStyles(
{
root: {
backgroundColor: "green"
}
},
{ name: "Hello" }
);

export default function App() {
const classes = useStyles();
return (
<div>
<h1 className={classes.root}>Hello CodeSandbox</h1>
</div>
);
}

Edit Control makeStyles class name prefix

Material-UI - Why should I use makeStyles instead of inline styles?

There are a few scenarios where using CSS classes (e.g. via makeStyles or withStyles) is necessary:

  • If you want to use media queries in your CSS
  • If you want to target pseudo-classes (e.g. :hover)
  • If you are creating a reusable customization of one of the Material-UI components and want to customize some of the classes that are conditionally applied to the element based on props or some other context (e.g. if you want to customize the "error" look of an Input while leaving it up to the places where the custom component is used to specify the error prop either directly or via the FormControl context)

As far as performance concerns, I would expect inline styles to be faster for most use cases. Whether the difference is enough to matter would depend on a lot of specifics regarding your particular application. The team I work with uses makeStyles or withStyles for most of our styling.

Inline styles can result in a lot of duplicated CSS in the DOM if a particular component is rendered many times within the document (e.g. list items, table cells, etc.). One nice thing about always using classes is that you can change the CSS for the class in the browser's developer tools and see that change applied throughout all its usages in the document.

Is there a performance difference between the sx prop and the makeStyles function in Material UI?

JSS is slightly faster than Emotion for static styles (i.e. styles that aren't dynamic based on props). JSS is much slower than Emotion for dynamic styles -- Emotion has similar performance for both static and dynamic styles.

You can find information about the performance difference for static styles between JSS and Emotion in the following issues:

  • https://github.com/mui-org/material-ui/issues/22342#issuecomment-696553225
  • https://github.com/mui-org/material-ui/pull/22173#issuecomment-673486269

JSS was about 10% faster than Emotion for static styles. For dynamic styles, JSS was 6 times slower than Emotion in one test the Material-UI team performed, and this is why JSS was eliminated from the list of possible styling engines for v5.

The documentation at https://next.material-ui.com/system/basics/#the-sx-prop contains the following performance information:
































Benchmark caseCode snippetTime normalized
a. Render 1,000 primitives<div className="…">100ms
b. Render 1,000 components<Div>120ms
c. Render 1,000 styled components<StyledDiv>160ms
d. Render 1,000 Box<Box sx={…}>370ms

How to style components using makeStyles and still have lifecycle methods in Material UI?

What we ended up doing is stopped using the class components and created Functional Components, using useEffect() from the Hooks API for lifecycle methods. This allows you to still use makeStyles() with Lifecycle Methods without adding the complication of making Higher-Order Components. Which is much simpler.

Example:

import React, { useEffect, useState } from 'react';
import axios from 'axios';
import { Redirect } from 'react-router-dom';

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

import LogoButtonCard from '../molecules/Cards/LogoButtonCard';

const useStyles = makeStyles(theme => ({
root: {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
margin: theme.spacing(1)
},
highlight: {
backgroundColor: 'red',
}
}));

// Highlight is a bool
const Welcome = ({highlight}) => {
const [userName, setUserName] = useState('');
const [isAuthenticated, setIsAuthenticated] = useState(true);
const classes = useStyles();

useEffect(() => {
axios.get('example.com/api/username/12')
.then(res => setUserName(res.userName));
}, []);

if (!isAuthenticated()) {
return <Redirect to="/" />;
}
return (
<Container maxWidth={false} className={highlight ? classes.highlight : classes.root}>
<LogoButtonCard
buttonText="Enter"
headerText={isAuthenticated && `Welcome, ${userName}`}
buttonAction={login}
/>
</Container>
);
}
}

export default Welcome;

Difference between @mui/material/styles and @mui/styles?

Normally in v4, you'd import the style API from @material-ui/core/styles. This one uses JSS behind the scene:

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

In v5, they changed the brand name to MUI. As a result, the package name changed too:

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

But MUI v5 also drops the support for JSS (which makeStyles/withStyles are using), so they move those APIs to a legacy package called @mui/styles. (They plan to remove this API in v6, but there are some pushback. See this issue for more info)

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

And encourage the users to adopt a newer styling solution (sx, styled) using emotion as a default style engine:

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

So in summary, the difference between the @mui/material/styles and @mui/styles is that:



Leave a reply



Submit