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
を以下のように修正する。
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が適用される。
- 参考:Theming
CssBaseline
は、ブラウザ間の表示差異をなくし、意図通りにスタイリングを行なうためのもの。
ページのマージンが無くなり、背景色がtheme.palette.background.defaultで指定した色になる。
- 参考:css-baseline
MyAppBar.tsx
MyAppBar.tsx
をsrc
配下に新規に作成する。
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.tsx
をsrc
配下に新規に作成する。
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. 画面イメージ
ここまでで以下のような画面が作成されます。
6. 最後に
今回はMaterial UIを利用した画面のデザイン方法について説明しました。
Material UIを利用することで、画面のデザインが容易になり、新規アプリの開発が格段に早くなるので、是非使ってみてください。
次回は「Firebaseとの連携方法」について説明をします。
7. 関連記事
Reactに関する記事です。
- 第1回 2020年版 Node.js+Reactのインストール
- 第3回 2020年版 React+Firebaseでアプリを作成する
- 第4回 2020年版 既存のウェブサイトに React を追加する
- 第5回 2020年版 ReactのRechartsで新型コロナウイルス感染症対策サイトのデータを可視化する
- 第6回 2020年版 React+Firebaseで画像のアップロード(その1)
- 第7回 2020年版 React+Firebaseで画像のアップロード(その2)
- 第8回 2020年版 React+Firebaseで画像のアップロード(その3)
- 第9回 2020年版 ReactにStoryshotsを導入する