Material-UI makeStyles, useStyles, createStyles, and withStyles Explained

Styling hooks in Material-UI are an effective and exceptional tool for customizing components. However, the similarly-named hooks can be confusing to use.

In this post, I’ll explain what each hook does, when to use it, and which hooks are recommended for certain situations.

Code Sandbox with full React code is in the Resources section.

Material-UI withStyles

React had not yet introduced hooks back when Material-UI 3 was first released. Higher-order components were still a common method of adding functionality to base components.

Material-UI withStyles was the primary method for wrapping a component and passing style props to it. It is still a valid method to use today if for some reason you are still using higher-order components or still using React lifecycle methods.

However, it is not the ideal method. Preferably, you are using React hooks and the MUI makeStyles hook (more on that below). Another recommended method of component styling is to use StyledComponents. Here’s a very basic example of creating a StyledComponent.

Below is an example of using withStyles:

Material-UI withStyles
const styles = {
  root: {
    borderRadius: 12,
    backgroundColor: "blue"
  }
};

function HOCComponent(props) {
  const { classes } = props;
  return (
    <Button variant="contained" className={classes.root}>
      Higher-Order Button
    </Button>
  );
}

HOCComponent.propTypes = {
  classes: PropTypes.object.isRequired
};

export default withStyles(styles)(HOCComponent);

In my opinion, this is more confusing and verbose than the newer makeStyles hook.

Material-UI makeStyles

The makeStyles hook is the current (V4) “proper” way to create styles for components. The underlying logic is the same as withStyles according to the docs.

There’s one less import needed for makeStyles compared to withStyles (not shown in my code below). It’s also a few lines less of code and more readable in my opinion.

Material-UI makeStyles
const useStyles = makeStyles({
  root: {
    borderRadius: 12,
    backgroundColor: "blue"
  }
});

function HookComponent(props) {
  const classes = useStyles();
  return (
    <Button variant="contained" className={classes.root}>
      Hook Button
    </Button>
  );
}

export default HookComponent;

Importantly, makeStyles can be passed parameters to make styling dynamic. For example, I passed a prop for height in order to position a Material-UI Drawer inside a container in the linked article.

Material-UI’s styles can also be used in React applications independently of the rest of the MUI package. If you export @material-ui/core/styles it will include a default theme; @material-ui/styles will not.

Material-UI useStyles

In the docs we find detailed explanations of different styling syntax, and we always see makeStyles paired with useStyles. However, we never get an explanation of useStyles.

useStyles is simply the naming convention of the hook created and returned by makeStyles. useStyles definitely is a hook; try calling it outside of the function component and you will get an error.

useStyles can be used to pass params to makeStyles, as mentioned above.

Material-UI createStyles

createStyles is perhaps the most interesting of the four topics in this post because it is a fix to make TypeScript play nicely with MUI.

“Its only purpose is to defeat TypeScript‘s type widening when providing style rules to makeStyles/withStyles which are a function of the Theme.”

MUI Docs

The docs even mention that the createStyles function doesn’t do anything at runtime.

The docs go into a pretty long explanation here. Suffice to say, I appreciate that the MUI team came up with a quick way to appease TypeScript.

Here’s example usage from the docs quoted above:

const useStyles = makeStyles((theme: Theme) => createStyles({
  root: {
    backgroundColor: theme.color.red,
  },
}));

Resources

Are you looking for training in Material-UI? Check out my review of the best Material-UI course in Udemy, which has 40+ hours of content and a 30-day money back guarantee.

YouTube version of this post

Code Sandbox Link

Share this post:

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.