Skip to content

How to integrate Material UI library in React apps

Published:

7 min read

Material design was introduced by Google around 2014 as a design language and it still shares some popularity among web and mobile applications. One of the common ways to integrate and use this design system in React apps is through MaterialUI library.

ss1

In this post, let us take a look at how to integrate a material library that is available as an npm module and consists of built React components that you can use to build apps. You are going to learn from scratch on how to install and configure this library as well as build a small demo app.

ss8

Prerequisites

Before you begin this tutorial you are going to need the following:

Create a new React app

To start, you are going to need to setup a React project. Let’s use npx to do so. Execute the following command in a terminal window.

npx create-react-app reactmaterial

By using the npx command (a part of the Node Package Manager (npm)) you execute create-react-app without the need to download and install the package globally.

When the new project is done scaffolding with the default dependencies such as React library and React DOM library installed.

Change in the new directory and you are going to be welcomed by the following structure of files and folders.

ss2

To verify that the React app is working, (you can totally skip the step at this time), run yarn start from the terminal window and open the default React app running at http://localhost:3000 in a browser window.

ss3

Install Material UI library

The next step is to install the Material-UI library and integrate it to work with the current React app. The first is to install the core dependency of this library.

yarn add @material-ui/core

Material-UI was designed with the Roboto font in mind. If you wish to use it, you can follow the instructions. Go back to the terminal window and install the typeface package of the font. Also note that, the following steps to install this font are optional.

yarn add typeface-roboto

Then go to the entry point of your React app (preferably, ./src/index.js file) and import the font.

// rest of the import statements
import "typeface-roboto";

Alternatively, if you do not wish to install the above npm module for the font, you can also use the CDN version of the font and read about it here.

Using AppBar to create a custom navigation bar

In this section let us build a navigation bar. Create a new file called ./src/components/Navbar.js and start by importing the components AppBar, ToolBar, and Typography from the MaterialUI library.

The AppBar component is used to display branding, screen titles, and navigation of the web app. That is what you are going to use it for. The ToolBar component is wrapper where you can place your components horizontally. The Typography component applies the Material UI theme that is available by default.

import React from "react";
import { AppBar, Toolbar, Typography } from "@material-ui/core";

Next, export a function component called Navbar with the following JSX.

export default function Navbar() {
  return (
    <AppBar>
      <Toolbar>
        <Typography variant="h6">React and Material-UI App</Typography>
      </Toolbar>
    </AppBar>
  );
}

In the code snippet above, notice the variant prop on the Typography component. It uses the variant mapping to properly associate a UI element with an HTML semantic element (such as h6 in the code snippet).

Now, to see it in action, import the Navbar component in the App.js file.

import React from "react";
import Navbar from "./components/Navbar";

function App() {
  return (
    <div>
      <Navbar />
    </div>
  );
}

export default App;

You are going to get the following result after this step.

ss4

Implementing a Paper component

Two components that are going to be used in this section in order to layout a view for the items of the list are called Grid and Paper.

Material Design’s responsive UI is based on a 12-column grid layout. The Grid component helps you implement this layout system and then provide the values or the number of grids you want to display. A basic grid might look like below:

ss5

Material UI uses CSS’s Flexbox to manage layout alignments and sizing of the grid columns.

The other component Paper actually displays the physical properties of a paper on the screen. It resembles a flat, texture of a sheet of paper, and using a prop called elevation you can manipulate its default display behavior. Do note that, this component does need an initial width and height.

Create a new component file called ./src/components/List.js which is going to be used as a reusable component later. This presentational component is going to display a Paper component inside Grid with custom styles.

import React from "react";
import { Grid, Paper, makeStyles } from "@material-ui/core";

const useStyles = makeStyles(theme => ({
  root: {
    marginTop: 100,
    flexGrow: 1,
  },
  paper: {
    height: 220,
    width: 340,
    backgroundColor: "#ebebeb",
  },
  avatarImage: {
    width: 200,
    height: 200,
    borderRadius: 100,
  },
}));

export default function List() {
  const classes = useStyles();

  return (
    <Grid container spacing={2}>
      <Grid item className={classes.root} xs={12}>
        <Grid container justify="center" spacing={2}>
          <Grid key={1} item>
            <Paper className={classes.paper} elevation={2} />
          </Grid>
        </Grid>
      </Grid>
    </Grid>
  );
}

The makeStyles comes from the Material UI API. It links a style sheet with a function component and returns a hook that you use inside the component.

You can modify the App.js file to include the List component.

// rest of the import statements
import List from "./components/List";

function App() {
  return (
    <div>
      <Navbar />
      <List />
    </div>
  );
}

Here is the result you are going to get after this step.

ss6

Fetching random user data

To display data inside List component, let us use https://randomuser.me/ API. In the App component the data is going to be fetched on the initial render using useEffect hook. The useState hook is used to store the fetched data by defining a state variable whose initial value is an empty array.

To start, first, import the hooks from the react library.

import React, { useState, useEffect } from "react";

After that create a state variable called data inside the App component. Along with the data variable, define two other state variables, isLoading to track the whether app is in loading mode (that is, the data is being fetched from the API) and error to track if there is an error while fetching the data. The loading state of the React app is going to be true by default.

function App() {
  const [data, setData] = useState([]);
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState("");

  //rest of the code
}

The useEffect hook is going to have a callback that is going to fetch the data using JavaScript’s fetch API.

useEffect(() => {
  fetch("https://randomuser.me/api/?results=5")
    .then(res => res.json())
    .then(
      result => {
        setIsLoading(false);
        setData(result.results);
      },
      error => {
        setIsLoading(false);
        setError(error);
      }
    );
}, []);

You can conditionally render the JSX based on the state variables.

if (isLoading) {
  return <div>Loading ...</div>;
} else if (error) {
  return <div>There is an error fetching data.</div>;
} else {
  return (
    <div>
      <Navbar />
      <List />
    </div>
  );
}

Now, when you refresh the React app, you are going to see the JSX being rendered that is related to the loading state of the app, for split seconds.

ss7

Display a list of users

You can now pass the user information you want to display in the form of the prop at the List component. Use JavaScript’s map function to traverse the array data.

{
  data.map(item => (
    <List
      key={item.id.value}
      userAvatar={item.picture.large}
      firstName={item.name.first}
      lastName={item.name.last}
    />
  ));
}

These props are then passed as arguments to the List component.

xport default function List({ userAvatar, firstName, lastName }) {
  const classes = useStyles();

  return (
    <Grid container spacing={2}>
      <Grid item className={classes.root} xs={12}>
        <Grid container justify="center" spacing={2}>
          <Grid key={1} item>
            <Paper className={classes.paper} elevation={2}>
              <Grid container justify="center">
                <Avatar
                  alt="User"
                  className={classes.avatarImage}
                  src={userAvatar}
                />
                <Typography variant="p">
                  Name: {firstName} {lastName}
                </Typography>
              </Grid>
            </Paper>
          </Grid>
        </Grid>
      </Grid>
    </Grid>
  );
}

The above code snippet uses few more core components from Material UI (such as Avatar). You can find their reference in the official documentation of this library.

Here is the final result you are going to get when you back to the browser screen.

ss8

Conclusion

I hope in this post, you get the idea of how you can leverage the core components of Material UI library in your React apps and save a ton of development time.

References:


Previous Post
Styling The React Native Way
Next Post
Chat app with React Native (Part 6) - Create a custom hook to change status bar styles

I'm a software developer and technical writer. On this blog, I share my learnings about both fields. Recently, I have begun exploring other topics, so don't be surprised if you find something new here.

Currently, working as a documentation lead at Expo.