★前回の記事
Appbarはいわゆるwebページのヘッダーで、ロゴやメニューなどを表示するのに使用します。 今回はログイン機能とナビゲーション機能をAppbarに載せます。ディレクトリ階層の変更とファイル名の変更も行います。
変更前と変更後のコンポーネントの位置関係は以下のようになります。
ディレクトリ階層の変更
Appbarのコンポーネントをheaderディレクトリにまとめます。
src/components/header
ディレクトリを作成します。src/components/login/index.js
をsrc/components/header/Login.js
にリネームします。src/components/navbar/index.js
をsrc/components/header/MenuIcons.js
にリネームします。
src/components/header/MenuIcons.js
のNavbar
変数をMenuIcons
変数にリネームします。
const MenuIcons = ({uid}) => { // 変更 // 略 } MenuIcons.propTypes = { // 変更 // 略 } MenuIcons = withRouter(connect( // 変更 mapStateToProps )(MenuIcons)) // 変更 export default MenuIcons // 変更
headerにAppbarとToolbarを使用する
Appbarを作成していきます。
src/components/header/index.js
(新規作成)
import React from 'react' import AppBar from '@material-ui/core/AppBar' import Toolbar from '@material-ui/core/Toolbar' import MenuIcons from './MenuIcons' import Login from './Login' const Header = () => ( <AppBar> <Toolbar> <MenuIcons /> <Login /> </Toolbar> </AppBar> ) export default Header
headerコンポーネントをAppコンポーネントに追加します。
src/components/App.js
import PropTypes from 'prop-types' // 追加 import { withStyles } from '@material-ui/core/styles' // 追加 import Header from './header/' // 追加 // import Navbar from './navbar/' は削除 // import Login from './login/' は削除 // stylesを追加 const styles = theme => ({ toolbar: theme.mixins.toolbar, }) const App = ({classes}) => ( // classesを追加 <BrowserRouter> <div> <CssBaseline /> {/* <Login /> は削除 */} {/* <Navbar /> は削除 */} <Header /> {/* 追加 */} <div className={classes.toolbar} /> {/* #1 */} <Switch> {/* 略 */} </Switch> </div> </BrowserRouter> ) // propTypesを追加 App.propTypes = { classes: PropTypes.object.isRequired, } export default withStyles(styles)(App) // 変更
- Headerの下に、
classes.toolbar
を適用した<div>
を追加します(#1)。Appbarはフローティングしているので、下のメニューを、toolbarの高さぶん下にする必要があるため、この要素を追加しています。試しにこのdiv要素を外してみると、最近の更新とAppbarが重なってしまうことがわかります。
ここまでの実行結果です。
今回はAppbarのpositionがデフォルト設定のfixedなので、 スクロールしてもAppbarが上部に表示されます。
Appbarとブラウザの端の間に空白が開いてしまう場合は、<CssBaseline>
の設定が足りていないので、下記記事を参考に設定してください。
タイトルの追加とMenuIconの変更
左側にタイトルを表示してHomeへのリンクを作成します。右側にタスク一覧へのリンクとログイン機能を配置します。
src/components/header/index.js
import { Link } from 'react-router-dom' // 追加 import PropTypes from 'prop-types' // 追加 import { withStyles } from '@material-ui/core/styles' // 追加 import Typography from '@material-ui/core/Typography' // 追加 // stylesを追加 const styles = theme => ({ grow: { flexGrow: 1, }, }) const Header = ({ classes }) => ( // classesを追加 <AppBar> <Toolbar> {/* Typographyを追加 */} <Typography variant="h6" color="inherit" component={Link} to="/"> タスク管理アプリ </Typography> <div className={classes.grow}></div> {/* 追加 */} <MenuIcons /> <Login /> </Toolbar> </AppBar> ) // propTypesを追加 Header.propTypes = { classes: PropTypes.object.isRequired, } // withStylesで囲む export default withStyles(styles)(Header)
タスク編集へのリンクはIconButton
を使用します。Tooltipを使用して、ボタンにマウスカーソルが重なると"編集"というテキストが現れるようにします。
src/components/header/MenuIcons.js
({/* xxx */}
のコメントは実行前に削除してください)
import { Link } from 'react-router-dom' // 追加 // import { NavLink, withRouter } from 'react-router-dom' は削除 import IconButton from '@material-ui/core/IconButton' // 追加 import Tooltip from '@material-ui/core/Tooltip' // 追加 import EditIcon from '@material-ui/icons/Edit' // 追加 const MenuIcons = ({uid}) => ( {/* 既存のコードは削除して書き直す */} <React.Fragment> { uid && <Tooltip title="編集"> <IconButton color="inherit" component={Link} to={`/users/${uid}/todos`} aria-label="編集"> <EditIcon /> </IconButton> </Tooltip> } </React.Fragment> ) // withRouterを削除 export default connect( mapStateToProps )(MenuIcons)
実行結果です。Appbarの左側にタイトル、右側に編集へのリンクとログイン表示がされました。リンクが機能していることを確認してください。
以上でログイン機能とナビゲーション機能をMaterial-UIのAppBarに載せることができました。
参考
★次回の記事
★目次