yucatio@システムエンジニア

趣味で作ったものいろいろ

Material-UIのAppBarを使用する(STEP 4 : Material-UIの導入 - React + Redux + Firebase チュートリアル)

★前回の記事

yucatio.hatenablog.com

Appbarはいわゆるwebページのヘッダーで、ロゴやメニューなどを表示するのに使用します。 今回はログイン機能とナビゲーション機能をAppbarに載せます。ディレクトリ階層の変更とファイル名の変更も行います。

変更前と変更後のコンポーネントの位置関係は以下のようになります。

f:id:yucatio:20181208154126p:plain

ディレクトリ階層の変更

Appbarのコンポーネントをheaderディレクトリにまとめます。

  1. src/components/headerディレクトリを作成します。
  2. src/components/login/index.jssrc/components/header/Login.jsにリネームします。
  3. src/components/navbar/index.jssrc/components/header/MenuIcons.jsにリネームします。

src/components/header/MenuIcons.jsNavbar変数を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が重なってしまうことがわかります。

ここまでの実行結果です。

f:id:yucatio:20181208154517p:plain

今回はAppbarのpositionがデフォルト設定のfixedなので、 スクロールしてもAppbarが上部に表示されます。

f:id:yucatio:20181208154532p:plain

Appbarとブラウザの端の間に空白が開いてしまう場合は、<CssBaseline>の設定が足りていないので、下記記事を参考に設定してください。

yucatio.hatenablog.com

タイトルの追加と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の左側にタイトル、右側に編集へのリンクとログイン表示がされました。リンクが機能していることを確認してください。

f:id:yucatio:20181208154723p:plain

以上でログイン機能とナビゲーション機能をMaterial-UIのAppBarに載せることができました。

参考

★次回の記事

yucatio.hatenablog.com

★目次

yucatio.hatenablog.com