React × Reduxの連載記事の4回目です。
前回までで簡単なカウンターアプリがReact Reduxで出来上がっている状態なので、次はデザイン周りの実装をしていきたいと思います。
今回はMaterial-UIを追加実装してみたいと思います。
- Material-UIの実装方法
この記事のターゲットとなる環境
現在の環境状況や前提条件を書いておきます。
- Mac OS Catalina ver 10.15.3
- 3日目の記事内容まで理解している
- 環境ターゲット(2020-03-11現在最新)- React16.13
- Redux7.2
- webpack4.42
- babel7.8.7
- eslint6.8
- Material-UI4.9.5
 
これまでのReact×Reduxの連載記事はこちらからどうぞ
http://hirooooo-lab.com/react-redux/Material-UIとは
Material-UIはGoogleの提唱しているマテリアルデザインを、Reactアプリに反映させることができるUIコンポーネントです。
Material-UI公式サイト
MaterialUIの公式サイトは一通り見ておきましょう。
[blogcard url=”https://material-ui.com/”]
現時点(2020/03/11)では、v4.9.5が最新バージョンになっています。
Material-UIはバージョンアップデートの頻度がかなり高いコンポーネントなので、定期的に公式サイトをウォッチしておくことをオススメです。
Material-UIのインストール
material-ui/coreのインストール
ターミナルから以下のnpmコマンドでMaterial-UIパッケージをインストールします。
$ npm install --save  @material-ui/coresvgiconのインストール
svgアイコンも使用したいので、一緒にインストールしておきます。
$ npm install --save @material-ui/iconsこれで必要なモジュールのインストールは完了です。
Appでテーマファイルを作成して読み込む
Material-UIThemeの作成
material-uiで使用するテーマファイルを作成します。
公式サイトを見てもらうとわかるんですが、せっかくなので独自のテーマファイルを作って設定してみたいと思います。
container/AppContainer.jsxに以下のソースを追加してオリジナルのMaterial-UIテーマを作成しましょう。
import { MuiThemeProvider, createMuiTheme } from '@material-ui/core/styles'
...
...
...
const theme = createMuiTheme({
  palette: {
    primary: Colors.purple,
    secondary: Colors.green,
  },
});テーマについて詳しくはこちらを見ておくと良いと思います。
[blogcard url=”https://material-ui.com/customization/theming/”]
ThemeProviderで読み込み
ThemeProviderを追加して作成したテーマを反映させます。
container/AppContainer.jsxのreturnを以下のように変更します。
  return (
    <MuiThemeProvider theme={theme}>
      <div>
        <Header />
        <Counter counter={counter} counterActions={counterActions} />
      </div>
    </MuiThemeProvider>
  );container/AppCountainer.jsx
追加したcontainer/AppCountainer.jsxはこんな感じになります。
import React, { useMemo } from 'react';
import { bindActionCreators } from 'redux';
import { useDispatch, useSelector } from 'react-redux';
import { MuiThemeProvider, createMuiTheme } from '@material-ui/core/styles';
import * as Colors from '@material-ui/core/colors';
import Header from '../components/header/HeaderComponent';
import Counter from '../components/counter/CounterComponent';
import { increment, decrement } from '../slices/counter';
const useActions = (actions, deps) => {
  const dispatch = useDispatch();
  return useMemo(
    () => {
      if (Array.isArray(actions)) {
        return actions.map((a) => bindActionCreators(a, dispatch));
      }
      return bindActionCreators(actions, dispatch);
    },
    deps ? [dispatch, ...deps] : [dispatch],
  );
};
const theme = createMuiTheme({
  palette: {
    primary: Colors.lightBlue,
    secondary: Colors.yellow,
  },
});
const AppContainer = () => {
  const counterActions = useActions({ increment, decrement });
  const counter = useSelector((state) => state.counter);
  return (
    <MuiThemeProvider theme={theme}>
      <div>
        <Header />
        <Counter counter={counter} counterActions={counterActions} />
      </div>
    </MuiThemeProvider>
  );
};
export default AppContainer;
これでAppContainer配下のコンポーネントでMaterial-UIのテーマが反映されます。
準備は整ったので、実際にコンポーネントをMaterial-UIコンポーネントに変更していきたいと思います。
HeaderをAppBarにしてみる
HeaderComponent.jsxにAppBarを追加する
前回のHeader.jsxにAppBarコンポーネントを追加してみます。
前回のHeaderComponent.jsxに必要なコンポーネントのimportを追加して、AppBarコンポーネントに変更します。
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 Typography from '@material-ui/core/Typography';
import Button from '@material-ui/core/Button';
import IconButton from '@material-ui/core/IconButton';
import MenuIcon from '@material-ui/icons/Menu';
import * as Colors from '@material-ui/core/colors';
const useStyles = makeStyles((theme) => ({
  root: {
    flexGrow: 1,
  },
  menuButton: {
    marginRight: theme.spacing(2),
  },
  title: {
    flexGrow: 1,
  },
  appBar: {
    color: Colors.common.white,
  },
}));
const HeaderComponent = () => {
  const classes = useStyles();
  return (
    <header>
      <AppBar className={classes.appBar} position="fixed">
        <Toolbar>
          <IconButton edge="start" className={classes.menuButton} color="inherit" aria-label="menu">
            <MenuIcon />
          </IconButton>
          <Typography variant="h6" className={classes.title}>
            カウンターアプリ
          </Typography>
          <Button color="inherit">Login</Button>
        </Toolbar>
      </AppBar>
    </header>
  );
};
export default HeaderComponent;
AppBarコンポーネントについては、公式サイトのデモを少し変更して使いました。
useStyleでmakeStylesのスタイル定義をclassesに読み込んでいます。
詳しくは公式サイトのAppBarのページには他にもいろんなサンプルがあるので見てみるといいと思います。
[blogcard url=”https://material-ui.com/components/app-bar/”]
実行してみる
ターミナルからnpm startで実行してみてください。
こんなページになったらOKです。

Counterのボタンを変更してみる
CounterComponent.jsxにMaterialボタンを追加
カウンターの増加・減少ボタンもMaterial-UIのButtonに変更してみたいと思います。
必要なコンポーネントのインポート
import { makeStyles } from '@material-ui/core/styles';
import Button from '@material-ui/core/Button';
import AddIcon from '@material-ui/icons/AddCircle';
import RemoveIcon from '@material-ui/icons/RemoveCircle';上記のコンポーネントを利用して、buttonタグをButtonタグに変更していきます。
Buttonタグに変更
returnしているelementのbuttonをButtonタグに変更して、以下のようにpropsを設定してみてください。
  return (
    <div>
      <h2>
        count={counter.value}
      </h2>
      <Button
        className={classes.button}
        variant="contained"
        color="primary"
        startIcon={<AddIcon />}
        onClick={() => counterActions.increment()}
      >
        増加
      </Button>
      <Button
        className={classes.button}
        variant="contained"
        color="secondary"
        startIcon={<RemoveIcon />}
        onClick={() => counterActions.decrement()}
      >
        減少
      </Button>
    </div>
  );Buttonについても公式サイトのButtonページに詳しく書いてありますので、一度見てみるのをオススメします。
[blogcard url=”https://material-ui.com/components/buttons/”]
CounterComponent.jsxの全体像
import React from 'react';
import PropTypes from 'prop-types';
import { makeStyles } from '@material-ui/core/styles';
import Button from '@material-ui/core/Button';
import AddIcon from '@material-ui/icons/AddCircle';
import RemoveIcon from '@material-ui/icons/RemoveCircle';
const useStyles = makeStyles((theme) => ({
  button: {
    margin: theme.spacing(1),
  },
}));
const CounterComponent = (props) => {
  const { counter, counterActions } = props;
  const classes = useStyles();
  return (
    <div>
      <h2>
        count={counter.value}
      </h2>
      <Button
        className={classes.button}
        variant="contained"
        color="primary"
        startIcon={<AddIcon />}
        onClick={() => counterActions.increment()}
      >
        増加
      </Button>
      <Button
        className={classes.button}
        variant="contained"
        color="secondary"
        startIcon={<RemoveIcon />}
        onClick={() => counterActions.decrement()}
      >
        減少
      </Button>
    </div>
  );
};
CounterComponent.propTypes = {
  counter: PropTypes.shape({
    value: PropTypes.number,
  }).isRequired,
  counterActions: PropTypes.shape({
    increment: PropTypes.func,
    decrement: PropTypes.func,
  }).isRequired,
};
export default CounterComponent;
実行結果
ボタンにMaterial-UIが反映されて、primaryカラーの増加ボタンとsecondaryカラーの減少ボタンが表示されたと思います。

Material-UI実装編まとめ
ざっくりですがMaterial-UIの実装方法を書いてみました。
結構簡単にマテリアルデザイン反映ができると思います。
Material-UIは公式サイトのドキュメントが結構充実して書いてありますので、サンプルを含めやりたいようなことは大体公式ドキュメントを見れば実装できると思います。
コンポーネントの種類もたくさんあるので、まずは自分で公式サイトをみてから、Try AND Errorで試してみるのが一番だと思います。
- Material-UIの実装は必要なモジュールをimportして書き換えるだけ
- 公式サイトのドキュメントを見れば大体のことは書いてある
- イロイロ自分でいじくり回してみるのが一番!!
次回予告
次回予告というかやろうと思ってること
- Redux Toolkitから作成するDucksパターンで実装する[jin_icon_check_circle]完了
- ESLintでAirbnbのスタイルガイドを実装する[jin_icon_check_circle]完了
- Materialデザインを実装する[jin_icon_check_circle]完了
- カスタムCSSを実装する
- ページルーティングを実装する
- 開発環境の効率化をするためにHotReloadとソースマップを実装する
- REST通信を実装する
- ログイン制御のフローを実装する
- デプロイ方法を検討、実装する
次の記事はこちら
http://hirooooo-lab.com/development/react-redux-import-css-for-webpack/勉強するならプログラミングスクールがベスト
今からプログラミングを勉強してプロのエンジニアを目指すなら、プログラミングスクールで勉強するのがベストです!
最短4週間で未経験からプロを育てるオンラインスクールなので、自宅からプログラミングやアプリ開発を学ぶことができます。












コメント