How to use Material UI in React
Tags: material, materialui, react, typescript
Published: 2020-01-21 18:27:03

---
title: How to use Material UI in React
published: true
description: How to create a performant and SEO-oriented application with Material UI and React
tags: material, materialui, react, typescript,
cover_image: https://thepracticaldev.s3.amazonaws.com/i/xhi4feokqjtz8h4c0ii3.jpg
series: React and Material UI
---

Building complex user interfaces is never easy. For this reason, sometimes it makes sense using CSS frameworks that can help us not wasting our time reinventing the wheel.
In this article, I show how to use Material UI components building a React-based application useful to display some football data. In particular, the Italian highest league, Serie A.

# Introduction
## Creating the project and install necessary dependencies
To easily get started with `create-react-app` I run the following:
```bash
npx create-react-app serie-a-almanac --template typescript
cd serie-a-almanac
npm install --save typescript @types/node @types/react @types/react-dom @types/jest
```

To install Material UI and Material UI Icons:
```bash
npm install @material-ui/core @material-ui/icons
```

Finally, I need to import the font in the `<head></head>` of `index.html`
```html
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" />
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons" />
```

## Defining the basic architecture of the application
Before rushing into the code, I always try to define the basic design of my application. In this phase, I try to imagine my application as more layers.

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/vkue4xmxsyc21hyro5r3.png)
![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/akxxhyhro2in3i2kz613.png)

This is enough to get started.

## The project structure
This last preparation phase is, in my opinion, the most important. It's important to me find the best way to arrange components into folders and subfolders.
This is how I arranged the code generated by `create-react-app`

```
...
/src
  /components
    /App
      App.css
      App.test.tsx
      App.tsx
  /images
    logo.svg
  index.css
  index.tsx
  react-app-env.d.ts
  serviceWorker.ts
  setupTests.ts
package.json
...
```

## Building the main container, `App.tsx`
This container is responsible for displaying the header bar and the content corresponding to the URL the user navigates.

### The `AppBar`

```typescript
import React from 'react';

import { createStyles, makeStyles, Theme } from '@material-ui/core/styles';
import {
  AppBar,
  Toolbar,
  Typography,
  IconButton,
 } from '@material-ui/core';
import MenuIcon from '@material-ui/icons/Menu';

const useStyles = makeStyles((theme: Theme) =>
  createStyles({
    root: {
      flexGrow: 1,
    },
    menuButton: {
      marginRight: theme.spacing(2),
    },
    title: {
      flexGrow: 1,
    },
  }),
);

const App: React.FC = () => {
  const classes = useStyles();

  return (
    <div className={classes.root}>
      <AppBar position="static">
        <Toolbar>
          <IconButton edge="start" className={classes.menuButton} color="inherit" aria-label="menu">
            <MenuIcon />
          </IconButton>
          <Typography variant="h6" className={classes.title}>
            Football Almanac
          </Typography>
        </Toolbar>
      </AppBar>
    </div>
  );
}

export default App;
```

> The `CSS-in-JS` solution unlocks many great features (theme nesting, dynamic styles, self-support, etc.) so I decided to give it a chance, at least while working with Material UI.

This is what I obtain
![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/jir0ozj9ywza8h6m276s.png)

### The `Drawer`

Change the `App.tsx` file as follows

```typescript
import { Drawer } from '@material-ui/core';

......

return (
  <div>
    <div className={classes.root}>
      ...
    </div>
    <Drawer open={true}>
      Hello Drawer!
    </Drawer>
  </div>
);
```

Et voila'!

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/eobcogo1c5gicpw3cnzk.png)

To make this component working properly I need to manage its `open|close` state.

```typescript
......
  const [isOpen, setIsOpen] = useState(false);
  const toggleDrawer = (open: boolean) => (
    event: React.KeyboardEvent | React.MouseEvent,
  ) => {
    if (
      event.type === 'keydown' &&
      ((event as React.KeyboardEvent).key === 'Tab' ||
        (event as React.KeyboardEvent).key === 'Shift')
    ) {
      return;
    }

    setIsOpen(open);
  };
  
  return (
    <div>
      <div className={classes.root}>
        <AppBar position="static">
          <Toolbar>
            <IconButton edge="start" className={classes.menuButton} color="inherit" aria-label="menu" onClick={toggleDrawer(true)}>
              <MenuIcon />
            </IconButton>
            <Typography variant="h6" className={classes.title}>
              Football Almanac
            </Typography>
          </Toolbar>
        </AppBar>
      </div>
      <Drawer open={isOpen} onClose={toggleDrawer(false)}>
        Hello Drawer!
      </Drawer>
    </div>
  );
```

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/31eo5vprgv3l9e9pgmqb.gif)

# What's next
In the next step I will create the drawer and I will add some client side navigation with React Router DOM.

# Useful resources
- `npx` https://www.npmjs.com/package/npx, https://dev.to/sarscode/npx-vs-npm-the-npx-advantage-1h0o
- `create-react-app` https://github.com/facebook/create-react-app/blob/master/README.md, https://reactjs.org/docs/create-a-new-react-app.html
- Material UI https://material-ui.com/