ReactでMuiのSnackbarをカスタマイズする

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

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

  • MuiのSnackbarの使い方を知りたい
  • Snackbarを汎用的に使えるようにしたい

Snackbarとは?

Snackbarは、ユーザーに簡単な情報、通知、またはアクションの提案を表示するためのものです。

一般的には、エラー情報を表示するために使用したり、

ユーザー登録などの一連の作業が完了した際に表示させることが多いです。

今回は、簡単にオシャレなSnackbarを使えるMuiというライブラリを使用して、

実装したいと思います。公式サイトは、こちらになります。

準備

まず、Muiを利用するためには、インストールをする必要があります。

私はnpm派なので、npmを使用してインストールを行います。

公式サイトからコマンドを拾ってくるのが安全かと思います。

ちなみに私は、いつもデフォルトを使用しています。

ここまで出来れば、Snackbarを作成する準備は完了です。

実装

今回は汎用的に使用したいのでコンポーネント化をしたいと思います。

プロジェクトの起動確認

まずは、作成したプロジェクトが上手く動くか確認しましょう。

npm run start

うまく動作することを確認出来たら、App.tsxをきれいに整えましょう。

import './App.css';

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

export default App;

Snackbar実装(ほぼ初期状態)

いよいよSnackbarの実装をしていきます。

まずは、CustomSnackbar.tsxファイルを作成して、そこに作っていきましょう。

import Snackbar from '@mui/material/Snackbar';

/**
 * 呼び出し先から持ってくる値
 * open:     Snackbarの開閉用
 * onClose:  Snackbarを閉じるためのトリガー
 */
type Props = {
  open: boolean
  onClose: () => void
}

export default function CustomSnackbar(props: Props) {

  return (
    <Snackbar
      open={props.open}
      anchorOrigin={{ vertical: 'top', horizontal: 'center' }}
      onClose={props.onClose}
      autoHideDuration={3000}
      message="I love snacks"
    />
  );
}

次は、呼び出し元のApp.tsxに追記していきます。

import { Box, Button, SnackbarOrigin } from '@mui/material';
import './App.css';
import CustomSnackbar from './CustomSnackbar';
import { useState } from 'react';

function App() {
  // Snackbarの開閉用
  const [open, setOpen] = useState<boolean>(false);

  // ボタンを押したときの処理
  const handleClick = () => {
    setOpen(true);
  };

  // Snackbarを閉じるための処理
  const handleClose = () => {
    setOpen(false);
  };

  return (
    <div className="App">
      <Box sx={{ display: 'flex', justifyContent: 'center' }}>
        <Button onClick={() => handleClick()}>
          Click Me!
        </Button>
      </Box>
      <CustomSnackbar open={open} onClose={handleClose} />
    </div>
  );
}

export default App;
最低限の機能しかもっていない状態のSnackbar

カスタマイズ(完成形)

これで、Snackbarの実装は出来ましたので、あとはカスタマイズしていくだけです。

ここからは、一番楽しい時間ですね!

CustomSnackBarの修正

まずは、CustomSnackbarのほうから修正していきます。

import { Alert, Button, IconButton } from '@mui/material';
import Snackbar from '@mui/material/Snackbar';
import { Fragment } from 'react';

/**
 * 呼び出し先から持ってくる値
 * open:              Snackbarの開閉用
 * onClose:           Snackbarを閉じるためのトリガー
 * message:           表示するメッセージ
 * autoHideDuration:  自動で非表示にするまでの時間
 * severity:          カラー
 */
type Props = {
  open: boolean
  onClose: () => void
  message: string
  autoHideDuration: number
  severity: 'success' | 'error' | 'warning' | 'info'
}

export default function CustomSnackbar(props: Props) {

  return (
    <Snackbar
      open={props.open}
      anchorOrigin={{ vertical: 'top', horizontal: 'center' }}
      onClose={props.onClose}
      autoHideDuration={props.autoHideDuration}
    >
      <Alert
        severity={props.severity}
        action={
          <Button color="inherit" size="small" onClick={props.onClose}>
            OK
          </Button>
        }>
        {props.message}
      </Alert>
    </Snackbar>
  );
}

ここで、簡単にpropsについて解説します。

propsという名前にはしていますが、型の名前をつけているだけなので何でもOKです。

propsは、一言で言うと呼び出す時に持ってきたい値(オブジェクト)のことです。

どう言う時に使うかというと、コンポーネントを分けたいときや、

コンポーネントごとに異なる値を表示させたいときや、値を流動的にしたいときに使われます。

参考書などでは、値の受け渡しと書かれていたりします。

今回の例だと、スナックバーの開閉タイミングやメッセージなどを、

コンポーネント単位で変化させたいので、propsに設定しています。

カスタムコンポーネントの実装

最後に、App.tsxを修正して完了です。

import { Box, Button, SnackbarOrigin } from '@mui/material';
import './App.css';
import CustomSnackbar from './CustomSnackbar';
import { useState } from 'react';

function App() {
  // Snackbarの開閉用
  const [open, setOpen] = useState<boolean>(false);

  // ボタンを押したときの処理
  const handleClick = () => {
    setOpen(true);
  };

  // Snackbarを閉じるための処理
  const handleClose = () => {
    setOpen(false);
  };

  return (
    <div className="App">
      <Box sx={{ display: 'flex', justifyContent: 'center' }}>
        <Button onClick={() => handleClick()}>
          Click Me!
        </Button>
      </Box>
      <CustomSnackbar
        open={open}
        onClose={handleClose}
        message='閉じないで。。。お願い。。'
        autoHideDuration={2000}
        severity='success'
      />
    </div>
  );
}

export default App;

27行目から32行目でCustomSnackbarの呼び出しをしています。

そのプロパティにCustomSnackbarで定義したpropsを設定しています。

ポイントとしては、閉じるときにApp.tsx側で作成した関数をコンポーネントに渡している点です。

このようにすることで、コンポーネント側から閉じる処理が実行できるようになります。

最初のうちは理解しづらいので何度も試して拡張していくと自分だけのコンポーネントを作れるようになります。

実行結果は以下です。

カスタマイズ後のSnackbar

最後に

ここまで読んでいただきありがとうございます。

今回は、Snackbarのカスタマイズをしてみました。

今回のような修正が全てではなく、無限にカスタイズ出来るので、色々試してみてください!

コメント

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