【React-Redux】Material-UI実装編 [初心者入門4日目]

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/core

svgiconのインストール

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で試してみるのが一番だと思います。

次回予告

次回予告というかやろうと思ってること

  • 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週間で未経験からプロを育てるオンラインスクールなので、自宅からプログラミングやアプリ開発を学ぶことができます。

よかったらシェアしてね!

コメント

コメントする

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)

目次
閉じる