LoginSignup
2
3

More than 3 years have passed since last update.

Material-UIを使ってダイアログを表示するには?

Posted at

Material-UIを使ってダイアログを表示するには一筋縄ではいかずパラメータを渡す必要があります。
なので今回は「Material-UIを使ってダイアログを表示する方法」を紹介します。

ダイアログ表示.gif

この機能は3つのファイルで構成されています。

  1. 一覧画面(index.jsx)
  2. アイテムコンポーネント(item.jsx)
  3. ダイアログコンポーネント(dialog.jsx)

1.一覧画面

WS000000.JPG

index.jsx
import React from 'react';
import Box from '@material-ui/core/Box';
import Item from "@comp/item";
import Grid from '@material-ui/core/Grid';
import { makeStyles } from '@material-ui/core/styles';

const useStyles = makeStyles((theme) => ({
  gridItem: {
    marginTop: theme.spacing(2),
  },
}));

// 表示するアイテムのリスト
const bookList = [
  {
    id: 1,
    title: "ファスト&スロー",
    page: 100,
    image: "http://books.google.com/books/content?id=tNDza_Pb0UMC&printsec=frontcover&img=1&zoom=5&edge=curl&source=gbs_api"
  },
  {
    id: 2,
    title: "ファストフードの恐ろしい話",
    page: 200,
    image: "http://books.google.com/books/content?id=ghgzDwAAQBAJ&printsec=frontcover&img=1&zoom=5&edge=curl&source=gbs_api"
  },
  {
    id: 3,
    title: "英語でおもてなし・ファストフード食べ歩き",
    page: 300,
    image: "http://books.google.com/books/content?id=HC-gCAAAQBAJ&printsec=frontcover&img=1&zoom=5&edge=curl&source=gbs_api"
  },
]

export default function Index(props) {
  const classes = useStyles();
  const compProps = {
    gridItem: {
      item         : true,
      space        : 5,
      xs           : 12,
      md           : 6,
      lg           : 3,
      className    : classes.gridItem
    }
  }

  return (
    <>
      <Box mx={10} mt={4}>
        <Box display="flex" alignItems="center">
          <h2>{props.title}</h2>
        </Box>
        <Grid container spacing={1}>
          {bookList.map(item =>
            <Grid {...compProps.gridItem} key={item.id}>
              <Item 
                bookParam={item}
                />
            </Grid>
          )}
        </Grid>
      </Box>
    </>
  );
}


一覧画面(index.jsx)では定義したリストを順番に並べて表示しています。

まずは、表示するリストのデータを定義しています。通常はAPIやDBから取得したりしますが、今回は見本なので直接定義しています。

そして、定義したリストデータをループで回して各アイテムをBookCardというコンポーネントで表示しています。各データはbookParamという名前でBookCardコンポーネントに渡しています。

2.アイテム

WS000001.JPG

item.jsx
import React, {useState} from 'react';
import Dialog  from "@comp/dialog";
import Typography from '@material-ui/core/Typography';
import Box from '@material-ui/core/Box';
import Link from '@material-ui/core/Link';

const item = (props) => {

  /** 画面パラメータ */
  const [dialogOpenF, setDialogOpenF] = useState(false);

  /**
   * コンポーネントに渡す引数
   */
  const compProps = {
    bookShowDialog: {
      open : dialogOpenF,                     //ダイアログの表示プローアティ
      bookParam: props.bookParam,
      onClose: () => setDialogOpenF(false),   //ダイアログ非表示処理
    },
    showLink: {
      href: "#",
      onClick: () => setDialogOpenF(true)     //ダイアログ表示処理
    }
  }

  return (
    <Box>
      {/* 画像の表示 */}
      <Link {...compProps.showLink}>
        <img src={props.bookParam.image}/>
      </Link>

      {/* タイトルの表示 */}
      <Typography>
        <Link {...compProps.showLink}>
        {props.bookParam.title}
        </Link>
      </Typography>

      {/* ページ数の表示 */}
      <Typography>{props.bookParam.page}ページ</Typography>

      {/* ダイアログの表示 */}
      <Dialog {...compProps.bookShowDialog} />
    </Box>
  );
}

export default item;

各アイテム(item.jsx)では呼び出し元から渡されたデータの表示とダイアログの表示・非表示の処理を行っています

引き渡されたパラメータはprops.bookParamに格納されているため画像URL(image)、タイトル(title)、ページ数(page)をそのまま出力に利用しています。

そして、最後のDialogコンポーネントに各アイテムの情報を渡しています。

2-1.ダイアログの表示・非表示

ダイアログ表示・非表示用のパラメータdialogOpenFを用意しています。このパラメータをtrue・falseに更新することでダイアログの表示・非表示に切り替えているわけです。

後は画像とタイトルがクリックされたときにdialogOpenFを更新するメソッドsetDialogOpenFを使ってtrueに変更しています。これによりopenプロパティーが更新されダイアログが表示されます。

そして、ダイアログが閉じる処理を行ったときにsetDialogOpenFでfalseを指定してダイアログを非表示に更新しています。

3.ダイアログ

WS000002.JPG

dialog.jsx
import React from 'react';
import Button from '@material-ui/core/Button';
import Dialog from '@material-ui/core/Dialog';
import DialogActions from '@material-ui/core/DialogActions';
import DialogContent from '@material-ui/core/DialogContent';
import DialogContentText from '@material-ui/core/DialogContentText';
import DialogTitle from '@material-ui/core/DialogTitle';
import PropTypes from 'prop-types';
import Typography from '@material-ui/core/Typography';

const dialog = (props) => {

  const compProps = {
    dialog: {
      open: props.open,           //ダイアログの表示・非表示プロパティ
      onClose: props.onClose,     //ダイアログが閉じられた時の処理
      scroll:'paper',
    },
    dialogContent: {
      dividers: true
    },
    dialogContentText: {
      tabIndex: -1
    },
    closeButton: {
      onClick: props.onClose,     //閉じるボタンが押されたときの処理
      color: "primary"
    },
  }

  return (
      <Dialog {...compProps.dialog}>
        {/* タイトル */}
        <DialogTitle>{props.bookParam.title}</DialogTitle>

        {/* 画像とページ数 */}
        <DialogContent {...compProps.dialogContent}>
          <img src={props.bookParam.image} />
          <DialogContentText {...compProps.dialogContentText}>
            <Typography>{props.bookParam.page}ページ</Typography>
          </DialogContentText>
        </DialogContent>

        {/* 閉じるボタン */}
        <DialogActions>
          <Button {...compProps.closeButton}>
            閉じる
          </Button>
        </DialogActions>
      </Dialog>
  );
}

dialog.propTypes = {
    open: PropTypes.bool,       //表示フラグ
    onClose: PropTypes.func,    //閉じる処理
  }

  export default dialog;

最後にダイアログに呼び出し元から渡された情報を出力します。

DialogTitleにはアイテムのタイトル。DialogContentにはアイテムの画像とページ数を表示。そして、ダイアログを閉じる処理を行う「閉じるボタン」を定義します。

閉じるボタンが押されたときは呼び出し元から引き渡されたprops.onCloseを利用します。これにより、呼び出し元からダイアログを非表示にします。

また、propTypesで呼び出し元からのパラメータの型をチェックしまています。openはダイアログの表示・非表示でboolean型。onCloseは閉じる処理でfunc型。これにより異常な値が渡ってこれば警告が表示されるようになっているのです。

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3