10
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

React初心者のための Material-UI 【Dialogの使い方編】

Posted at

React + Material-UI を勉強しています。今日は「ダイアログ」「モーダル」などと呼ばれる機能の使い方をまとめます。

React のチュートリアルは一通り終えていざ自分で作ろうとするとつまずくことがあるかと思います。なかでも Material-UI の公式ページは便利だけど理解し辛いなあと思うので「使い方」の点からまとめます。ちなみに Dialog ってのはこんな奴ですね。GIFはMaterial-UI のサンプルページです。

2020-08-09 12.25.21.mov.gif

大雑把なプロセスは

  • Dialog のデザインを決める
  • Dialog を含むコンポーネントを作る SampleDialog
  • SampleDialog を開くトリガーを作る
  • state のリフトアップ

となります。

ダイアログのデザインを決める

Dialog を含むコンポーネントのデザインを決めます。直接 <Dialog /> に props を渡せるなら一手間省けますが、今回はひとまわりラッピングされたコンポーネントを想定します。

コンポーネントを作る

ダイアログとトリガーのコンポーネントを作ります。ここでは仮に SampleDialog, SampleCard と名付けます。トリガーのコンポーネントは Card にするつもりなので SampleCard と名付けました。 SampleCard のなかの Button をクリックしてダイアログを開くようにしたいと思います。

図のような構造になります。

trigger-dialog-Page-4.png

SampleDialog を開くトリガーを作る

SampleDialog を開くトリガーを作ります。つまり、 SampleCard のなかに Button を配置します。


class SampleCard extends React.Component {
  render() {
    return (
      <Card>
        <CardContent>Lorem ipsum dolor sit amet</CardContent>
        <CardActions>
          <Button variant="contained" color="primary">
            Open Dialog!
          </Button>
        </CardActions>
      </Card>
    );
  }
}

state のリフトアップ

このセクションがいちばん大変ですね笑。

React では2つ以上のコンポーネントで状態のやりとりをするために共通の親コンポーネントを作り state を一元化するという手法を取ります。これを state のリフトアップと呼んでいます。今回の場合は SampleDialog と SampleCard の間で open という bool 値を共有する必要があります。それを仮に Parent と名付けます。 Parent の state に open を用意します。

trigger-dialog-Copy of Page-4.png

ダイアログを開く

  1. SampleCard 内部の Button がクリックされる
  2. Parent の open が true になる
  3. SampleDialog の props.open が true になりダイアログが開く

というステップがあります。 では、1 から 2 を繋ぐにはどうすればいいのでしょうか?子コンポーネントから親コンポーネントの state をいじるのはできません。そのため、親コンポーネントから渡す props に親コンポーネントの state を変更するメソッドを渡します。たとえば、handleOpen というメソッドを作ります。中身は this.setState({open: true}) です。つまり、 Parent の state を変更するメソッドです。そして、 constructor でメソッドを.bind(this)しておきます(ここは説明不十分だと思います。後日追記する予定)。

trigger-dialog-Copy of Copy of Page-4.png
そして、このメソッドを SampleCard に渡します。
trigger-dialog-Copy of Copy of Copy of Page-4-2.png
Card の props にonClick: handleOpen が入っていますね。これを Button への props に渡すことで 1 から 2 へのステップが実現します。
trigger-dialog-Copy of Page-8-3.png

2から3へのステップは簡単です。Parent から SampleDialog に渡された props.open を<Dialog> に渡します。これでダイアログを開けるようになりました。

ダイアログを閉じる

Dialog は Backdrop(ダイアログの背景、つまり本体より外側の部分)をクリックすると onClose がコールバックされます。onCloseで Parent の open を false にすればダイアログも閉じられます。「ダイアログを開く」でやったのと同じように

  • Parent で メソッド handleClose を定義する
  • Parent から SampleDialog へ props でonClose={handleClose}を渡す

というステップです。

わかりにくかった点

Material-UI のサンプルは Hooks を使ったコードです。それを知らずに読んでいると混乱してしまいました。「俺の知ってる React じゃないぞ???」となりました笑。

おわり

途中で力尽きたので、コードサンプルは載せていません。気が向けば書きます笑。

自分を含めた初心者のための備忘録として書いています。間違い、もっとよい方法などございましたらぜひ教えてください。

参考

https://material-ui.com/api/dialog/
Dialog の props を調べられます。いろいろカスタムできます。

10
8
3

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
10
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?