【備忘録】日本一わかりやすいReact-Redux講座 実践編 #9 「ネイティブアプリ風ヘッダーを作ろう」


はじめに

概要

この記事は、トラハック氏(@torahack_)が運営するYoutubeチャンネル『トラハックのエンジニア学習ゼミ【とらゼミ】』の『日本一わかりやすいReact-Redux講座 実践編』の学習備忘録です。

前回の講座では、Products の 詳細情報ページを作りました。

今回の講座では、Material-UI の <AppBar/>コンポーネントを利用して、ネイティブアプリ風のヘッダーを作成します。

※ 前回記事: https://qiita.com/ddpmntcpbr/items/1b1acf97a62cd5101884

動画URL

ネイティブアプリ風ヘッダーを作ろう【日本一わかりやすいReact-Redux講座 実践編#9】

要点

  • Material-UIの<AppBar>コンポーネントで、ヘッダーを作成できる。
  • Material-UIの<Badge>コンポーネントで、アイコンの肩に数字を表示できる。

完成系イメージ

http://localhost:3000

任意のページ上部にヘッダーが表示され、アプリ名ロゴと、各メニューアイコンが表示されています。

メニューアイコンはまだダミーの状態で、クリックしても何も起きません。また、カート右肩のバッジ数も、ダミーの値を表示させています。

メニューアイコンは、ログイン状態のときのみ表示させるため、サインイン画面では表示されません。

http://localhost:3000/signin

メイン

ヘッダーを作ろう

今回はとにかくMaterial-UIを用いて、ビューファイルをゴリゴリ書いていくだけです。

ヘッダーはアプリ内の任意のページ上部で表示をさせるため、App.jsxを親コンポーネントとして定義していきます。

src/components/直下に、新たにHeaderディレクトリを作り、

  • ヘッダー全体のコンポーネントとしてHeader.jsx
  • ヘッダー右側のメニューアイコン群を表示するコンポーネントしてHeaderMenu.jsx

を作成します。

実装ファイル(ヘッダー)
1.src/components/Header/Header.jsx
2.src/components/Header/HeaderMenus.jsx
3.src/components/Header/index.js
4.src/App.jsx
1.src/components/Header/Header.jsx
import React from 'react';
import {makeStyles} from '@material-ui/core/styles';
import AppBar from '@material-ui/core/AppBar';
import Toolbar from '@material-ui/core/Toolbar';
import logo from "../../assets/img/icons/logo.png";
import { useDispatch, useSelector } from 'react-redux';
import { getSignedIn } from '../../reducks/users/selectors';
import {push} from "connected-react-router"
import {HeaderMenus} from "./index"

const useStyles = makeStyles({
  root: {
    flexGrow: 1,
  },
  menuBar: {
    backgroundColor: "#fff",
    color: "#444",
  },
  toolBar: {
    margin: "0 auto",
    maxWidth: 1024,
    width: "100%"
  },
  iconButtons: {
    margin: "0 0 0 auto"
  }
})

const Header = () => {
  const classes = useStyles();
  const dispatch = useDispatch();
  const selector = useSelector((state)=>state)
  const isSignedIn = getSignedIn(selector)

  return (
    <div className={classes.root}>
      <AppBar position="fixed" className={classes.menuBar}>
        <Toolbar className={classes.toolBar}>
          <img
            src={logo} alt="Torahack Logo" width="128px"
            onClick={()=>dispatch(push("/"))}
          />
          {isSignedIn && (
            <div className={classes.iconButtons}>
              <HeaderMenus />
            </div>
          )}
        </Toolbar>
      </AppBar>
    </div>
  )
}

export default Header
  • <AppBar>の中に <Toolbar>を記述することで、ヘッダーを実装できます。
  • メニューアイコンを表示する<HeaderMenus>要素はログイン状態でのみ表示させたいので、{isSignedIn && ...で条件分岐しています。
2.src/components/Header/HeaderMenus.jsx
import React from "react";
import IconButton from "@material-ui/core/IconButton";
import Badge from "@material-ui/core/Badge";
import ShoppingCartIcon from "@material-ui/icons/ShoppingCart";
import FavoriteBorderIcon from "@material-ui/icons/FavoriteBorder";
import MenuIcon from "@material-ui/icons/Menu"

const HeaderMenu = () => {
  return (
    <>
      <IconButton>
        <Badge badgeContent={3} color="secondary">
          <ShoppingCartIcon />
        </Badge>
      </IconButton>
      <IconButton>
        <FavoriteBorderIcon />
      </IconButton>
      <IconButton>
        <MenuIcon />
      </IconButton>
    </>
  )
}

export default HeaderMenu
  • return文の中身は1つのHTML要素である必要があるので、<>...</>で全体を囲っています。
  • <Badge>コンポーネントで Icon をラッピングすることで、Icon の右肩に数値を表示させることができます。現在は、badgeContent={3}としてダミーの数値を表示させていますが、最終的にはここに「カートに入れた商品数」が入ります。
3.src/components/Header/index.js
export {default as Header} from "./Header"
export {default as HeaderMenus} from "./HeaderMenus"
  • エントリーポイントに追加します。
4.src/App.jsx
import React from 'react'
import Router from './Router'
import "./assets/reset.css"
import "./assets/style.css"
import {Header} from './components/Header'

const App = () => {
  return (
    <>
      <Header />
      <main className="c-main">
          <Router />
      </main>
    </>
  )
}

export default App;
  • App.jsxで Header を読み込み、全ページで表示させるようにします。

 動作確認

「完成系イメージ」と同様のため割愛します。

さいごに

今回の要点をおさらいすると、

  • Material-UIの<AppBar>コンポーネントで、ヘッダーを作成できる。
  • Material-UIの<Badge>コンポーネントで、アイコンの肩に数字を表示できる。

以上です!次回の講座で<MenuIcon />の中身を作っていく予定です。

このような学習内容を日々呟いていますので、よろしければTwitter(@ddpmntcpbr)のフォローもよろしくお願いします。