React を 触ってみた (3) – Material-UI
この記事は 2018年 4月 30日 に書かれた記事です。
今回は Material-UI を 使って Hello World を 装飾していきます
前回の記事
React を 触ってみた (2) – React + babel + webpack
https://tekuaru.jack-russell.jp/2018/04/29/1711/
React とは 関係ないので スタイルは 自分でどうにかする という人は 次回のパートまで 進んでしまって問題ないです
Material-UI の インストール
(Dir : /var/www/html/)
今回も 作成に必要な パッケージを インストールします
npm install --save-dev material-ui@next @material-ui/icons prop-types
各々のバージョンは 以下のようになりました
"@material-ui/icons": "^1.0.0-beta.43", "material-ui": "^1.0.0-beta.44", "prop-types": "^15.6.1",
Drawer を 表示させる
アプリっぽく ヘッダー サイドバー コンテンツ の アセットページが有ったので こちらを参考に 組み込んでいきます
I referred to Drawer - Material-UI.
https://material-ui-next.com/demos/drawers/
/src/component/main.jsx
import React from 'react'
import PropTypes from 'prop-types'
import { withStyles } from 'material-ui/styles'
import AppBar from 'material-ui/AppBar'
import Toolbar from 'material-ui/Toolbar'
import IconButton from 'material-ui/IconButton'
import MenuIcon from '@material-ui/icons/Menu'
import Hidden from 'material-ui/Hidden'
import Drawer from 'material-ui/Drawer'
import Divider from 'material-ui/Divider'
import List, { ListSubheader, ListItem, ListItemText } from 'material-ui/List'
import Typography from 'material-ui/Typography'
const drawerWidth = 240
const styles = theme => ({
root: {
flexGrow: 1,
height: '100vh',
zIndex: 1,
overflow: 'hidden',
position: 'relative',
display: 'flex',
width: '100%',
},
appBar: {
position: 'absolute',
marginLeft: drawerWidth,
[theme.breakpoints.up('md')]: {
width: `calc(100% - ${drawerWidth}px)`,
},
},
toolbar: theme.mixins.toolbar,
navIconHide: {
[theme.breakpoints.up('md')]: {
display: 'none',
},
},
drawerPaper: {
width: drawerWidth,
[theme.breakpoints.up('md')]: {
position: 'relative',
},
},
drawerListSubheader: {
backgroundColor: theme.palette.background.paper,
},
content: {
flexGrow: 1,
overflowY: 'scroll',
backgroundColor: theme.palette.background.default,
padding: theme.spacing.unit * 3,
},
})
class Main extends React.Component {
constructor (props) {
super(props)
this.state = {
mobileOpen: false,
}
}
handleToggleDrawer() {
this.setState({ mobileOpen: !this.state.mobileOpen })
}
render() {
const { classes, theme } = this.props
const drawer = (
<div>
<List>
<ListSubheader className={classes.drawerListSubheader} component="div">First List</ListSubheader>
<ListItem button>
<ListItemText primary="First List Button" />
</ListItem>
</List>
<Divider />
<List>
<ListSubheader className={classes.drawerListSubheader} component="div">Second List</ListSubheader>
<ListItem button>
<ListItemText primary="Second List Button" />
</ListItem>
</List>
</div>
)
return (
<div className={classes.root}>
<AppBar className={classes.appBar}>
<Toolbar>
<IconButton
color="inherit"
aria-label="open drawer"
onClick={() => this.handleToggleDrawer()}
className={classes.navIconHide}
>
<MenuIcon />
</IconButton>
<Typography variant="title" color="inherit" noWrap>
Title
</Typography>
</Toolbar>
</AppBar>
<Hidden mdUp>
<Drawer
variant="temporary"
anchor={theme.direction === 'rtl' ? 'right' : 'left'}
open={this.state.mobileOpen}
onClose={() => this.handleToggleDrawer()}
classes={{
paper: classes.drawerPaper,
}}
ModalProps={{
keepMounted: true, // Better open performance on mobile.
}}
>
{drawer}
</Drawer>
</Hidden>
<Hidden smDown implementation="css">
<Drawer
variant="permanent"
open
classes={{
paper: classes.drawerPaper,
}}
>
{drawer}
</Drawer>
</Hidden>
<main className={classes.content}>
<div className={classes.toolbar} />
<h1>Hello World</h1>
</main>
</div>
)
return <h1>Hello World</h1>
}
}
Main.propTypes = {
classes: PropTypes.object.isRequired,
theme: PropTypes.object.isRequired,
}
export default withStyles(styles, { withTheme: true })(Main)
わかりやすくするために タイトルの部分と コンテンツの部分は インデントを つけていません
サイドバー の 部分は drawer に 切り出してあるので サブタイトルの部分や リストの部分は わかりやすくなっているかなと思います
ページを確認
コンパイルをして ページを確認してみましょう
First React Project
http://react/
ページを 表示させたら 周りに margin が空いていました
というわけで index.html に normalize.css を 読み込ませてしまいましょう
/index.html
<head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.0/normalize.min.css"> </head>
無事 表示されました
Material-UI の 変数
Material-UI が 持っている変数は こちらで 確認できます
Default Theme - Material-UI
https://material-ui-next.com/customization/default-theme/
State と Props とは
React における State と Props の違い - Qiita
https://qiita.com/kyrieleison/items/78b3295ff3f37969ab50
上記のほうがわかりやすいので 読んでみてください
propTypes とは
ReactのPropTypes Validator - Qiita
https://qiita.com/park-jh/items/a7dc06a478b944e59222
上記のほうがわかりやすいので 読んでみてください
まとめ
バージョン違いなのか 環境の違いなのか 単純な コピペでは 動かなくて 試行錯誤しましたが
そのおかげで 少し理解が深まったかなって 思います
ほぼほぼ コピペだったので Material-UI の 詳しいことについては 別途 勉強しようと思います