React + Material-UIを使用してMaterial Designのコンポーネントを作成する


こんにちは、Gaji-Labo アシスタントエンジニアの石垣です。

最近案件などで Material-UI という React 用UIコンポーネントライブラリを触る機会が多くなり、知見が溜まってきたので今回は Material-UI の基本的な使い方についてまとめたいと思います。

Material-UI とは?

Material UI公式ドキュメントのキャプチャ画像

Material-UI は、 Google の Material Design をベースに作られた React 用UIコンポーネントライブラリです。

Material-UI を使うことで手軽に Material Design を取り入れたコンポーネントを作成することができるようになります。

また、それぞれのコンポーネントが Material Design に基づいてデザインされているのみでなく、色定義や間隔、タイポグラフィなど細かい面に至るまで Material Design をベースに変数によって定義されており、またそれを拡張することもできるため、サイト全体の幅広い領域で統一性を図ることが出来るのも大きな特徴です。

詳しくはこちらの公式ドキュメントをご覧ください。使用できるコンポーネントの詳細なドキュメントが用意されています。

Material-UI を使用してコンポーネントを作成する方法

まずは Material-UI を導入します。

$ yarn add @material-ui/core

@material-ui/core を導入することで、Material-UI のほとんどの機能を使用することが出来ます。

他には、 core には用意されていない特殊なコンポーネント群を追加導入する @material-ui/lab や、 Material Design にあるアイコン群を導入できる @material-ui/icons 等があります。

今回は Button コンポーネントを拡張したコンポーネントを TypeScript で作成するのを例にご紹介します。

コンポーネントを使用するには、使用したいコンポーネントを import してJSX内に置きます。

import * as React from "react";
import { Button, ButtonProps } from "@material-ui/core/";

type Props = React.ButtonHTMLAttributes<ButtonProps>;

export const ExampleButton: React.FC<Props> = () => {
  return (
    <Button variant="contained" color="primary">
      LABEL
    </Button>
  );
};

コンポーネントにはそれぞれスタイルの設定に必要な Props があらかじめ用意されており (Button の場合 variant, color など) 、それを変更することである程度の設定を行うことができます。

コンポーネントごとの Props の一覧も公式ドキュメントに記載されています。

作成した ExampleButton コンポーネント

スタイルや機能を Props を超えた範囲で拡張しない場合、そのまま置くだけで使用することができます。

TypeScript で記述する場合、コンポーネントごとに FooProps のような名称で型定義が用意されているため、それを同時に import して参照できます。

スタイルの拡張

Props で設定できる範囲を超えてスタイルを変更したい場合は、大きく分けて 2つの方法があります。

createMuiTheme を使用する方法

Material-UI には theme として各コンポーネントの規定のスタイルや、色変数 primary の定義などがあらかじめ定められています。

createMuiTheme 関数を使用することで、テーマの変数定義やコンポーネントのスタイルを変更することができます。

関数を任意の変数 (theme) に代入し、 ThemeProvider コンポーネントの theme props で呼ぶことで ThemeProvider で囲われた範囲のコンポーネントにテーマが適用されます。

import * as React from "react";
import { createMuiTheme, ThemeProvider } from "@material-ui/core/styles";
import { Button, ButtonProps } from "@material-ui/core/";

type Props = React.ButtonHTMLAttributes<ButtonProps>;

export const ExampleButton: React.FC<Props> = () => {
  const theme = createMuiTheme({
    overrides: {
      MuiButton: {
        root: {
          fontSize: "20px",
          lineHeight: 1.5,
          padding: "20px",
        },
        containedPrimary: {
          backgroundColor: "#ff9999",
        },
      },
    },
  });
  return (
    <ThemeProvider theme={theme}>
      <Button variant="contained" color="primary">
        label
      </Button>
    </ThemeProvider>
  );
};

コンポーネントの上書きは override プロパティ内で行います。override プロパティ内では scss のように入れ子でセレクタが書くことができ、 Material-UI コンポーネントの持つ Class 名をセレクタに指定することでそのスタイルを変更します。

名称の通りこの関数は全体のテーマを設定するものなのですが、こちらのやり方は以降で紹介する makeStyles と異なり、コンポーネントのスタイルを直接変更します。

デフォルトで Button コンポーネント (.MuiButton-containedPrimary) が持っているスタイル
createMuiTheme で上書きした Button コンポーネント (.MuiButton-containedPrimary) のスタイル

そのため CSSセレクタの詳細度を上げないので、現状はこのやり方を使ってコンポーネントのスタイルを変更するようにしています。

makeStyles を使用する方法

こちらのやり方では makeStyles 関数を使い、コンポーネントにスタイルを追加して上書きします。

使用する時はスタイルを上書きしたいコンポーネントに {classes.foo} の形で className を渡します。

import * as React from "react";
import { makeStyles } from "@material-ui/core/styles";
import { Button, ButtonProps } from "@material-ui/core/";

type Props = React.ButtonHTMLAttributes<ButtonProps>;

const useStyles = makeStyles({
  button: {
    padding: "20px",
    fontSize: "20px",
    lineHeight: 1.5,
    backgroundColor: "#ff9999",
  },
});

export const ExampleButton: React.FC = () => {
  const classes = useStyles();
  return (
    <Button variant="contained" color="primary" className={classes.button}>
      label
    </Button>
  );
};

こちらのやり方では styled-component に近い記法で記述することもできます。

makeStyles で上書きした Button コンポーネントのスタイル

makeStyles を使用すると makeStyles-button-6(数字はレンダリング毎に変わる) のような class が生成され、上書きされるので詳細度が createMuiTheme より深くなります。

スコープが生まれるので、特定のページでコンポーネントを上書きしたい時や、より堅牢なスタイルにしたい時にこれを使うと良さそうと感じました。

以上の2つのやり方を使い分けることによって、コンポーネントのスタイルを変更することができます。

まとめ

今回の記事では Material-UI を使用してコンポーネントを作成し、スタイルを変更する方法をまとめました。

今回はコンポーネントを作成するまでにとどまりましたが、今後より知見を溜めてもっと詳細な使い方やカスタマイズについても書いていきたいと思っています。

Material-UI に興味を持っている方の参考にしていただけると幸いです。

Gaji-Labo は React 開発の実績と知見があります

フロントエンド開発の専門家である私たちが御社の開発チームに入ることで、バックエンドも含めた全体の開発効率が上がります。

「人手が足りず信頼できるエンジニアを探している」
「Vue.js から React へリプレイスを検討している」
「フロントエンドの効率化をどうしたらいいか分からない」
「自分たちで手を付けてみたがいまいち上手くいかない」

フロントエンド開発に関わるお困りごとがあれば、まずは一度お気軽に Gaji-Labo にご相談ください。

オンラインでのヒアリングとフルリモートでのプロセス支援にも対応しています。

フロントエンドの相談をする!

投稿者 Ishigaki Shotaro

未経験から Gaji-Labo に入社。現在は React/TypeScript/Next.js の案件で MUI を使ったコンポーネント組み込みを担当。プロジェクトチームのリードとして共に組み込み作業をしているメンバーの進行管理も行っています。休日はだいたい家で音楽を聴いており、たまにライブに出かけています。