ReactでMUIを拡張した独自コンポーネントを作成

React_icon React
この記事は約7分で読めます。

この記事は以下の方を対象に書いています。

  • 汎用的なコンポーネントを作成したい
  • MUIに慣れてきたから、拡張してみたい

MUIを扱う準備

まずは、MUIのインストールを行います。

コマンドプロンプトやターミナルで、プロジェクトに移動して下記のコマンドを実行します。

npm install @mui/material @emotion/react @emotion/styled

詳しくは、MUIの公式サイトを確認してみてください。

これで準備は完了です。

コンポーネント作成

次に独自コンポーネントを作成します。

srcフォルダ配下に「CustomButton.tsx」というファイルを作成します。

今回は、分かりやすいようにsrcフォルダ配下ですが、

更にフォルダを作り、そこに独自コンポーネントを作成することが多いです。

今回はファイル名から分かるようにMUIのButtonを拡張したコンポーネントを作成します。

コンポーネントの大枠作成

まずは、コンポーネントの大枠を作成します。

import { Button } from "@mui/material";

export default function CustomButton() {

  return (
    <Button variant="outlined" color="error">
      Error
    </Button>
  );
};

次にApp.tsxから独自コンポーネント(CustomButton.tsx)を呼び出します。

import React from 'react';
import './App.css';
import CustomButton from './CustomButton';

function App() {
  return (
    <div className="App">
      <CustomButton />
    </div>
  );
}

export default App;

この状態で確認してみるとMUIの公式サイトに記載のあるデザインのまま表示されます。

ボタンのカスタマイズ

次は、独自コンポーネント(CustomButton.tsx)のデザインを拡張してみます。

11行目から21行目で、デザインを設定しています。

あとは、そのデザインをMUIのButtonタグのsxプロパティに渡すだけです。

今回は汎用的にするために、Propsを設定しデザインの適用有無を25行目で設定しています。

デザインが固定の場合は、25行目は「sx={style}」としてもOKです。

import { Button } from "@mui/material";

// 呼び出し時に渡すデータを定義
type Props = {
  hasStyle: boolean
}

// 引数にPropsを定義
export default function CustomButton(props: Props) {
  // 独自スタイルを定義
  const style = {
    margin: '10px',
    fontWeight: 'bold',
    backgroundColor: 'red',
    color: 'white',
    '&:hover': {
      backgroundColor: 'red',
      color: 'white',
      opacity: 0.7,
    },
  };

  return (
    // sxプロパティを呼び出すときによって、デザインの適用有無を設定
    <Button sx={props.hasStyle ? style : null} variant="outlined" color="error">
    // デザインが固定の場合
    // <Button sx={style} variant="outlined" color="error">
      Error
    </Button>
  );
};

次は、拡張した独自コンポーネントを呼び出します。

今回は呼び出し時にhasStyleを渡すように定義しているので、trueを渡します。

import React from 'react';
import './App.css';
import CustomButton from './CustomButton';

function App() {
  return (
    <div className="App">
      <CustomButton hasStyle={true} />
    </div>
  );
}

export default App;

これで完成です。

値の受け渡しについては、以下の記事でも解説しているので、良ければ参考にしてください。

デザインの比較

最後にデザインの比較をしてみます。

design-description

このように、デフォルトの背景が好みではない場合は、

デザインの拡張をして好みのデザインにすることが可能になります。

もちろん、デザインだけではなく、処理(ロジック)の拡張も可能です。

実用的なコンポーネント作成

ここでは、もう少し実用的な独自コンポーネントを紹介します。

独自テキストフィールド

テキストフィールドは、かなり使用頻度が高いため、

独自のコンポーネントを作っておくと、便利に使えると思います。

独自のコンポーネントを作るときのポイントは、

共通化したい部分と、共通化したくない部分を明確にしておくことです。

例えば、デザインは共通化しておいた方が良いです。

逆に、処理は共通化しないほうが良いと思います。

ただし、状況によるので、その時の状況に合わせて考えるのがベストです。

import { TextField } from "@mui/material";

type Props = {
  /** 最大化有無 */
  fullWidth?: boolean
  /** ラベル */
  label: string
  /** 値 */
  value: string
  /** 値変更時の処理 */
  setValue: (val: string) => void
  /** 補助用テキスト */
  helperText?: string
}

export default function CustomTextField(props: Props) {
  const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    props.setValue(event.target.value);
  };

  return (
    <TextField
      fullWidth={props.fullWidth}
      label={props.label}
      value={props.value}
      onChange={handleChange}
      helperText={props.helperText}
    />
  )
}
design-description2
独自テキストフィールド

これくらいの規模でも、かなり便利になるので、作っておくと良いと思います。

さらに、このコンポーネントをベースにして、別コンポーネントを作るのも良いと思います。

今回は、テキストフィールドの独自コンポーネントを作ってみましたが、

他の記事でも、独自コンポーネントを作っていますので、良ければ参考にしてください。

最後に

どうでしたでしょうか?

デザインの拡張は意外と簡単にできるので、試してみてください。

ただ、この手軽さもMUIがあってのものなので感謝ですね!

コメント

タイトルとURLをコピーしました