Noh | エンジニア向け情報共有コミュニティ
Signup / Login

Alert と Snackbar を組み合わせたメッセージの表示コンポーネントの紹介

javascript
typescript
mui
react

投稿日: 2024/06/26

MUI (旧 material-ui )の実用小ネタ集

フォームの保存時などエラーや成功のメッセージを表示したいと思います。

こんな感じです。

エラーや成功のメッセージの表示

このコンポーネントを使いやすいようにまとめたのでよければご使用ください。

AlertSnackbarコンポーネントの紹介

AlertSnackbarコンポーネントは以下のようになります。

AlertSnackbar.tsx

import { FC, SyntheticEvent } from "react" import Stack from "@mui/material/Stack" import Snackbar from "@mui/material/Snackbar" import Alert, { AlertColor } from "@mui/material/Alert" import IconButton from "@mui/material/IconButton" import CloseIcon from "@mui/icons-material/Close" export type AlertSnackbarState = { open: boolean body: string severity?: AlertColor } type Props = { alertSnackbarState: AlertSnackbarState setAlertSnackbarState: (state: AlertSnackbarState) => void } export const AlertSnackbar: FC<Props> = (props) => { const handleClose = (event: SyntheticEvent | Event, reason?: string) => { if (reason === "clickaway") { return } props.setAlertSnackbarState({ ...props.alertSnackbarState, body: "", open: false, }) } return ( <Stack spacing={2} sx={{ width: "100%" }}> <Snackbar open={props.alertSnackbarState.open} autoHideDuration={6000} onClose={handleClose} > <Alert variant="filled" severity={props.alertSnackbarState.severity} action={ <IconButton aria-label="close" color="inherit" size="small" onClick={handleClose} > <CloseIcon fontSize="inherit" /> </IconButton> } sx={{ mb: 2 }} > {props.alertSnackbarState.body} </Alert> </Snackbar> </Stack> ) }

ポイントとしてはhandleClosesetAlertSnackbarStateseverityを更新していないことです。
Snackbarを閉じるときにseverityを変更すると、一瞬異なる色が見えてちらついてしまいます。

同じ理由でbodyも更新しない方が良いのですが、間違ったメッセージを表示することが無いように消してます。

AlertSnackbarコンポーネントの使い方

AlertSnackbarState型のStateを作成して、これを更新することでメッセージの表示を制御します。

import { FC, useState } from "react" import { AlertSnackbar, AlertSnackbarState, } from "@/components/sharedComponents/AlertSnackbar/AlertSnackbar" export const ProfileForm: FC = () => { const [alertSnackbarState, setAlertSnackbarState] = useState<AlertSnackbarState>({ body: "", severity: undefined, open: false, }) const onSubmit = async () => { try { // Save or update process setAlertSnackbarState({ open: true, body: "更新しました", }) } catch (e) { setAlertSnackbarState({ open: true, body: "更新に失敗しました", severity: "error", }) } } return ( <> <form onSubmit={onSubmit}>{/* Something */}</form> <AlertSnackbar alertSnackbarState={alertSnackbarState} setAlertSnackbarState={setAlertSnackbarState} /> </> ) }
yosi

Noh を作ってるエンジニア。

目次