58
63

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

第2回 2020年版 ReactのMaterial UI V4の使い方について

Last updated at Posted at 2020-02-28

1.概要

ReactのMaterial UI V4の使い方について、基本的な利用方法について学習する。
Material UIを利用して、画面がデザインできるようになることを目標とする。

2. 前提条件

作業日時

  • 2020/2/28

ソフトウェアのバージョン

分類 ソフトウェア バージョン
フレームワーク React 16.13.0
フレームワーク React-dom 16.13.0
静的型付け TypeScript 3.8.3
Material UI v4.9.4
@material-ui/core 4.9.4
@material-ui/icons 4.9.1

3. 事前準備

Material UIを試すためのサンプル用アプリをcreate-react-appで作成する。
@material-ui/iconsは、表示も早く、綺麗なSVGアイコンを利用するためにインストールする。

$ npx create-react-app material-ui-sample --template typescript
$ cd material-ui-sample/
$ yarn add @material-ui/core @material-ui/icons

以下コマンドでローカルにサーバーを立上げ、ブラウザで画面イメージを確認しながら、編集を行う。プログラムを編集すると自動的に画面に変更が反映される。

$ yarn start

上記、コマンドで自動的にブラウザが起動するが、ブラウザを閉じてしまった場合などは、 http://localhost:8080/ でアクセスすることが可能。

4. サンプルアプリの作成

App.tsx

既存のApp.tsxを以下のように修正する。

/src/App.tsx
import React from "react";
import './App.css';
import { MuiThemeProvider, createMuiTheme } from '@material-ui/core/styles';
import CssBaseline from "@material-ui/core/CssBaseline";
import green from '@material-ui/core/colors/green';
import red from '@material-ui/core/colors/red';

// 独自に作成したコンポーネントのインポート
import MainContent from "./MainContent";
import MyAppBar from "./MyAppBar";

// 独自のテーマを作成する
const theme = createMuiTheme({
  palette: {
    //type: 'dark', // ダークテーマ
    primary: green,
    // primary: red,
  },
  typography: {
    fontFamily: [
      'Noto Sans',
      'sans-serif',
    ].join(','),
    fontSize: 12,
    h1: {
      fontSize: "1.75rem"
    },
    h2: {
      fontSize: "1.5rem"
    },
    h3: {
      fontSize: "1.25rem"
    },
    h4: {
      fontSize: "1.125rem"
    },
    h5: {
      fontSize: "1rem"
    },
    h6: {
      fontSize: "1rem"
    },
  }
});

function App() {

  return (
    <MuiThemeProvider theme={theme}>
        <CssBaseline />
        <MyAppBar />
        <MainContent />
    </MuiThemeProvider >
  );
}

export default App;

ソースの冒頭で各種必要なpackageをimportしている。
importの仕方は以下の2つ({}の有無)がある。{}無しはdefaultでexportされているものを読み込む。

  • import hoge from hogefuga
  • import {hoge, fuga} from hogefuga

createMuiThemeはMaterial UIのテーマを修正するために利用する。palette.primaryの色を指定するだけで、その色をベースとしたテーマにすることができる。
Themeを適用するためには <MuiThemeProvider theme={theme}>のタグで囲う必要がある。その配下でThemeが適用される。

CssBaselineは、ブラウザ間の表示差異をなくし、意図通りにスタイリングを行なうためのもの。
ページのマージンが無くなり、背景色がtheme.palette.background.defaultで指定した色になる。

MyAppBar.tsx

MyAppBar.tsxsrc配下に新規に作成する。

/src/MyAppBar.tsx
import React, { useState } from "react";
import { makeStyles, createStyles, Theme } from '@material-ui/core/styles';

import {
  AppBar,
  Toolbar,
  Typography,
  IconButton,
  Avatar,
  List,
  ListItem,
  ListItemIcon,
  ListItemText,
  Drawer,
  Divider,
} from '@material-ui/core';

// Material-UIアイコン取得
import SettingsIcon from '@material-ui/icons/Settings';
import InfoIcon from '@material-ui/icons/Info';
import HomeIcon from '@material-ui/icons/Home';
import MenuIcon from "@material-ui/icons/Menu";

// スタイルを適用する
const useStyles = makeStyles((theme: Theme) =>
  createStyles({
    headerLogo: {
      color: "inherit",
      marginRight: 20,
    },
    headerTitleStyle: {
      flexGrow: 1,
      color: "inherit",
    },
    menuButton: {
      color: "inherit",
      padding: '8px',
    },
    avatar: {
      margin: '8px',
    },
    drawerList: {
      width: 200,
      height: "100%"
    },
  }),
);

function MyAppBar() {

  // Drawerの状態
  const [isOpen, setOpen] = useState(false);

  // CSSを適用する。
  const classes = useStyles();

  // Drawerの状態を変更する関数。
  const toggleDrawerNav = () => {
    setOpen(!isOpen);
  };

  const closeDrawerNav = () => {
    setOpen(false);
  };

  return (
      <React.Fragment>
        {/* 上部のバー */}
        <AppBar position='static' aria-label="Global Navi">
          <Toolbar>
            <IconButton onClick={toggleDrawerNav} aria-label="SideMenu">
              <MenuIcon />
            </IconButton>
            <Typography className={classes.headerLogo} variant="subtitle1">My Sample App</Typography>
            <Typography className={classes.headerTitleStyle} variant="subtitle1" >Material UI test</Typography>
            <IconButton className={classes.menuButton} aria-label="Menu">
              <Avatar className={classes.avatar}></Avatar>
            </IconButton>
          </Toolbar>
        </AppBar>
        {/* サイドメニュー */}
        <Drawer open={isOpen} onClose={closeDrawerNav}>
          <div className={classes.drawerList}>
            <List>
              <ListItem button onClick={closeDrawerNav}>
                <ListItemIcon>
                  {<HomeIcon />}
                </ListItemIcon>
                <ListItemText primary={"Home"} />
              </ListItem>
              <ListItem button onClick={closeDrawerNav}>
                <ListItemIcon>
                  {<InfoIcon />}
                </ListItemIcon>
                <ListItemText primary={"Info"} />
              </ListItem>
              <ListItem button onClick={closeDrawerNav}>
                <ListItemIcon>
                  {<SettingsIcon />}
                </ListItemIcon>
                <ListItemText primary={"Setting"} />
              </ListItem>
            </List>
            <Divider />
          </div>
        </Drawer>
      </React.Fragment>
  );
}

export default MyAppBar;

const useStyles = makeStyles((theme: Theme) =>{}はMateril-uiでCSSを適用するための方法。
*他にもいくつかCSSを適用する方法はあります。
冒頭でクラス名と適用したいスタイルを宣言します。CSSの記法と多少異なるので注意が必要です。

実際に利用するには、まず、関数の中でconst classes = useStyles();を呼び出し、スタイルを適用したいコンポーネントに<Avatar className={classes.avatar}></Avatar>でクラス名を指定します。

const [isOpen, setOpen] = useState(false);ではReact HookのuseStateというものを利用しています。
useStateはconst [<変数名>, <変数に値を設定する関数名>] = useState(<初期値>);でstate(変数)を宣言することができます。ここではDrawerの状態を表す変数を宣言しています。

Material-uiのコンポーネントはimport {hoge} '@material-ui/core';でインポートしてから利用します。
アイコンはimport MailIcon from '@material-ui/icons/Mail';で利用します。

MainContent.tsx

続いて、MainContent.tsxsrc配下に新規に作成する。

/src/MainContent.tsx
import React from "react";
import { makeStyles, createStyles, Theme } from '@material-ui/core/styles';

import {
  Badge,
  CircularProgress,
  Paper,
  Button,
  Fab,
  Grid
} from '@material-ui/core';

// Material-UIアイコン取得
import MailIcon from '@material-ui/icons/Mail';
import ShareIcon from '@material-ui/icons/Share';
import ListAlt from '@material-ui/icons/ListAlt';
import PersonAdd from '@material-ui/icons/PersonAdd';
import Lock from '@material-ui/icons/Lock';
import Chat from '@material-ui/icons/Chat';
import Assessment from '@material-ui/icons/Assessment';
import CloudUpload from '@material-ui/icons/CloudUpload';
import AssignmentTurnedIn from '@material-ui/icons/AssignmentTurnedIn';
import AddIcon from '@material-ui/icons/Add';
import EditIcon from '@material-ui/icons/Edit';
import FavoriteIcon from '@material-ui/icons/Favorite';

// スタイルを適用する
const useStyles = makeStyles((theme: Theme) =>
  createStyles({
    root: {
      flexGrow: 1,
      padding: '10px',
    },
    paper: {
      padding: theme.spacing(2),
      textAlign: 'center',
      '& > *': {
        margin: theme.spacing(3),
      },
    },
  }),
);

function MainContent() {

  // CSSを適用する。
  const classes = useStyles();

  return (
        <Grid container className={classes.root} spacing={3}>
          <Grid item xs={12} justify="center" >
            <Paper variant="outlined" elevation={3} className={classes.paper}>
              <Button variant="contained">Default</Button>
              <Button variant="contained" color="primary">
                Primary
                </Button>
              <Button variant="contained" color="secondary">
                Secondary
                </Button>
              <Button variant="contained" disabled>
                Disabled
                </Button>
              <Button variant="contained" color="primary" href="#contained-buttons">
                Link
                </Button>
            </Paper>
          </Grid>
          <Grid item xs={12} justify="center" >
            <Paper variant="outlined" elevation={3} className={classes.paper}>
              <Fab color="primary" aria-label="add">
                <AddIcon />
              </Fab>
              <Fab color="secondary" aria-label="edit">
                <EditIcon />
              </Fab>
              <Fab disabled aria-label="like">
                <FavoriteIcon />
              </Fab>
            </Paper>
          </Grid>
          <Grid item xs={12} justify="center" >
            <Paper variant="outlined" elevation={3} className={classes.paper}>
              <CircularProgress />
            </Paper>
          </Grid>
          <Grid item xs={12} justify="center" >
            <Paper variant="outlined" elevation={3} className={classes.paper}>
              <Badge badgeContent={4} color="primary">
                <MailIcon fontSize="small" />
              </Badge>
              <Badge badgeContent={3} color="secondary">
                <MailIcon />
              </Badge>
              <Badge badgeContent={2} color="error">
                <MailIcon fontSize="large"/>
              </Badge>
            </Paper>
          </Grid>
          <Grid item xs={12} justify="center" >
            <Paper variant="outlined" elevation={3} className={classes.paper}>
                <ShareIcon />
                <ListAlt />
                <PersonAdd />
                <Lock />
                <Chat />
                <Assessment />
                <CloudUpload />
                <AssignmentTurnedIn />
            </Paper>
          </Grid>
        </Grid>
  );
}

export default MainContent;

5. 画面イメージ

ここまでで以下のような画面が作成されます。

Material-uiサンプル.png

6. 最後に

今回はMaterial UIを利用した画面のデザイン方法について説明しました。

Material UIを利用することで、画面のデザインが容易になり、新規アプリの開発が格段に早くなるので、是非使ってみてください。

次回は「Firebaseとの連携方法」について説明をします。

7. 関連記事

Reactに関する記事です。

58
63
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
58
63

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?