in Front End

Typing React (2) – Material-UI

This series focus on how to correctly use TypeScript in React application. The previous article explained some details in typing React itself, so this article will focus on Material-UI, one of the most popular UI library.

Previous articles:


Adding Material UI is as easy as npm install --save @material-ui/core. Generally speaking Material UI is well typed so there should be no problem using it in TypeScript. The only challenge is the CSS-in-JS. If you are using Material UI 3.x, probably you have to use the Higher Order Component way to integrate styles into your component:

// NOTE: This is for Material UI 3.x
import React from 'react';
import { Theme, createStyles, WithStyles, withStyles } from '@material-ui/core';

const styles = (theme: Theme) =>
  createStyles({
    root: {},
  });

export interface IProps extends WithStyles<typeof styles> {}

class Todo extends React.Component<IProps> {
  render() {
    const { classes } = props;
    return <div className={classes.root} />;
  }
};

export default withStyles(styles)(Todo);

This is perfect for class-style component, but might be a little weird for functional component. Fortunately Material UI team just released v4.0.0, which provides a new way using React hooks to inject styles. Let us see how it works:

// makeStyles only supported in Material UI 4+
import React from 'react';
import { Theme, makeStyles } from '@material-ui/core';

const useStyles = makeStyles((theme: Theme) => ({
  root: {
    border: `1px solid ${theme.palette.divider}`,
    shadow: theme.shadows[1],
  }
}));

const Todo: React.FC = () => {
  const classes = useStyles();
  return <div className={classes.root} />;
};

export default Todo;

This is definitely easier and cleaner than the HOC approach, and most importantly, the default export remains as a type so that it is possible to define generic component with styles.

Write a Comment

Comment