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/)
今回も 作成に必要な パッケージを インストールします
1 | npm install --save-dev material-ui@next @material-ui /icons prop-types |
各々のバージョンは 以下のようになりました
1 2 3 | "@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
001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020 021 022 023 024 025 026 027 028 029 030 031 032 033 034 035 036 037 038 039 040 041 042 043 044 045 046 047 048 049 050 051 052 053 054 055 056 057 058 059 060 061 062 063 064 065 066 067 068 069 070 071 072 073 074 075 076 077 078 079 080 081 082 083 084 085 086 087 088 089 090 091 092 093 094 095 096 097 098 099 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 | 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
1 2 3 4 5 | < 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 の 詳しいことについては 別途 勉強しようと思います