React NativeのAlertやらDialogやらmodalやら似たようなやつのそれぞれ特徴をまとめました。

# 似たような使い方をするAlertとDialogとModalの違い
ログインに失敗した時のエラーメッセージやユーザーに確認をとる時に使われるUIの作り方は何種類かあります。
その中で今回はReactNativeの標準に入っているAlert、ModalとライブラリのDialogの三つのそれぞれの違いをまとめました。
基本的にこの三つはほとんど同じUIで挙動や実装方法も同じです。ただ、Dialogじゃないとできないことなどもありましたので記事にしました。

# ライブラリをインストール
### dialog 
```yarn add react-native-dialog```
Github：https://github.com/mmazzarolo/react-native-dialog

# 実装
プロジェクトを作成し、各ライブラリをインポートします。

```javascript
import React from 'react';
import {Alert, Button, View,Modal} from 'react-native';
import Dialog from "react-native-dialog";
```

## １、Alert
初めにAlertを作っていきます

```javascript
import React from 'react';
import {Alert, Button, View,Modal} from 'react-native';
import Dialog from "react-native-dialog";


export const AlertDialog = () => {
  const onPressAlert = () => {
    Alert.alert(
        'アラートを出しました', 
        'テキストテキストテキストテキスト',
    [
      {
        text: 'Cancel',
        onPress: () => console.log('アラートのcancelをタップした時の挙動を書く'),
        style: 'cancel',
      },
      {text: 'OK', onPress: () => console.log('アラートのOKをタップした時の挙動を書く')},
    ]);
  };
  return (
    <View>
      <Button title="Alert" onPress={onPressAlert} />
    </View>
  );
};
```
Buttonをタップした時にAlertを表示させます。
配列の一つ目にstyle:'cancel'と書かれていますが、これは表示する文字の色、太さを変更することができます。
cancelだと太文字に、destructiveだと赤文字になります。

こんな感じで表示されます。
![スクリーンショット 2021-09-08 16.49.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1812049/cb6b0906-7316-feea-8898-2244c4a7a2b4.png)
　次に配列内のボタンを一つ増やしてみます。

```javascript
Alert.alert('アラートを出しました', 'テキストテキストテキストテキスト', [
      {
        text: 'setting',
        onPress: () =>
          console.log('アラートのsettingをタップした時の挙動を書く'),
        style: 'destructive',
      },
      {
        text: 'Cancel',
        onPress: () =>
          console.log('アラートのcancelをタップした時の挙動を書く'),
        style: 'cancel',
      },
      {
        text: 'OK',
        onPress: () => console.log('アラートのOKをタップした時の挙動を書く'),
      },
    ]);
```
すると。。。。
![スクリーンショット 2021-09-08 16.58.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1812049/03cf850a-6bac-6484-1283-b981a703101d.png)
配列内が三つ以上の時は縦並びになります。
###ここで一つ気になる点があります。
配列は一番目に「setting」、二番目に「Cancel」、三番目に「OK」としているのに実際はCancelが一番下になってます。
これは「Cancel」内のstyleに’cancel’としていると思いますが、cancelというstyleを当てると、例え一番目に入れていても表示する時は自動的に一番下になります。
便利っちゃー便利かな。

ちなみに配列を一つだけにするとこんな感じです
![スクリーンショット 2021-09-08 17.02.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1812049/a3770b12-5e98-0787-c802-caf49e047425.png)


## Alertの特徴
#### １、アラートの上に出すタイトル（テキスト）のスタイリングができない
→もし色やフォントサイズを変更したくても変えれないです。
#### ２、タイトルに画像やアイコンを入れられない
→基本テキストした入れないと思いますが、画像を入れたくても入れれないです。
#### ３、手軽に実装できるので特に変わった実装が必要じゃない時はこれで十分かな
→できることは少ないですが、Alertの内容だけで十分なことがほとんどだと思うので、基本的にはこれを使えばいい

補足ですが、実装するときにアラートの第二引数(テキスト)を入れたくなくて消してしまうと

```javascript
 Alert.alert('アラート',[
      {
        text: 'setting',
        onPress: () =>
          console.log('アラートのsettingをタップした時の挙動を書く'),
        style: 'destructive',
      },
      {
        text: 'Cancel',
        onPress: () =>
          console.log('アラートのcancelをタップした時の挙動を書く'),
        style: 'cancel',
        type:'login-password',
      },
      {
        text: 'OK',
        onPress: () => console.log('アラートのOKをタップした時の挙動を書く'),
      },
    ],
   );
```
![スクリーンショット 2021-09-08 17.21.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1812049/20a9640d-618c-f4d9-5b16-840549e39b5c.png)
こんな感じに思ったUIにならないので、二行目にテキストが必要ない場合でも

```javascript
 Alert.alert('アラート','',[
      {
        text: 'setting',
        onPress: () =>
          console.log('アラートのsettingをタップした時の挙動を書く'),
        style: 'destructive',
      },
      {
        text: 'Cancel',
        onPress: () =>
          console.log('アラートのcancelをタップした時の挙動を書く'),
        style: 'cancel',
        type:'login-password',
      },
      {
        text: 'OK',
        onPress: () => console.log('アラートのOKをタップした時の挙動を書く'),
      },
    ],
   );
```
こんな感じで空にしといてください！

## Dialog
実装していきます

```javascript
import React,{useState} from 'react';
import {Alert, Button, View,Modal} from 'react-native';
import Dialog from 'react-native-dialog';

export const AlertDialog = () => {
  const [visible,setVisible] = useState(false)
  return (
    <View>
      <Button title="Alert" onPress={()=>setVisible(true)} />
      <View>
        <Dialog.Container visible={visible}>
            <Dialog.Title>ダイアログを出しました</Dialog.Title>
            <Dialog.Description>
                あああああああああああああああああああああああああああああああああああ
            </Dialog.Description>
            <Dialog.Button label="Cancel" color='red' onPress={()=>setVisible(false)} />
            <Dialog.Button label="OK" onPress={()=>setVisible(false)} />
        </Dialog.Container>
      </View>
    </View>
  );
};
```
Alertではタップした時にAlertを出すようにしましたが、Dialogではvisibleがtrueの時に表示、falseで非表示にします。
ですのでuseStateを使ってtrueかfalseかを制御します。
Buttonをタップした時にtrueにし、ダイアログ内のボタンをタップすることでfalseとなり、非表示になります
![スクリーンショット 2021-09-08 18.04.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1812049/3b44b2de-e4a0-4d15-af49-50af00c14146.png)
こんな感じで表示されます。Alertとほぼ同じですね。

では色々Dialogの特徴を紹介していこうと思います。

```javascript
 <View>
    <Dialog.Container visible={visible}>
        <Dialog.Title style={{fontSize:30,marginBottom:40}}>ダイアログを出しました</Dialog.Title>
        <Dialog.Description>
            あああああああああああああああああああああああああああああああああああ
        </Dialog.Description>
        <Dialog.Button label="Cancel" color='red' onPress={()=>setVisible(false)} />
        <Dialog.Button label="OK" onPress={()=>setVisible(false)} />
        <Dialog.Button label="Setting" bold={true} onPress={()=>setVisible(false)} />
    </Dialog.Container>
 </View>
```
まずスタイリングですがtitleにもstyleを当てることができます。またボタンの方はカラーや太さを調整することができます。
こんな感じに表示されます。
![スクリーンショット 2021-09-08 18.15.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1812049/bf9f6f48-c039-5940-9008-5478dc45c2bf.png)
Alertの時は三つボタンがあると縦並びになりましたが、Dialogだと横並びに続いていきます。

### さらにこんな事もできます

```javascript
 <View>
    <Dialog.Container visible={visible}>
        <Dialog.Title style={{fontSize:30,marginBottom:40}}>
          <Icon name="user-o" size={70} />
        </Dialog.Title>
        <Dialog.Input placeholder='名前' />
        <Dialog.Button label="Cancel" color='red' onPress={()=>setVisible(false)} />
        <Dialog.Button label="OK" onPress={()=>setVisible(false)} />
        <Dialog.Button label="Setting" bold={true} onPress={()=>setVisible(false)} />
    </Dialog.Container>
  </View>
```
Dialog.title内をテキストではなく、アイコンを表示させています。
Alertではできませんでしたが、画像やアイコンも入れることができるんです。

そのほかにもDialog.inputでテキスト入力欄をダイアログにつけることができます！
![スクリーンショット 2021-09-08 18.20.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1812049/878252e4-a214-f933-596d-bf9a4d2131eb.png)

## Dialogの特徴
##### １、Alertよりできることが多い
##### ２、スタイルを当てることができる
##### ３、画像やアイコンを入れることができる

## Modal
最後のModalです、実装していきます

```javascript
import React, {useState} from 'react';
import {Alert, Button, View, Modal, StyleSheet, Text} from 'react-native';
import Dialog from 'react-native-dialog';
import Icon from 'react-native-vector-icons/FontAwesome';

export const AlertDialog = () => {
  const [modalVisible, setModalVisible] = useState(false);
  return (
    <View>
      <Button title="タップ" onPress={() => setModalVisible(true)} />
      <View>
        <Modal
          animationType="slide"
          transparent={true}
          visible={modalVisible}
          onRequestClose={() => {
            Alert.alert('Modal has been closed.');
            setModalVisible(!modalVisible);
          }}>
          <View style={styles.centeredView}>
            <View style={styles.modalView}>
              <Text style={styles.modalText}>Hello World!</Text>
              <Button title="閉じる" onPress={() => setModalVisible(false)} />
            </View>
          </View>
        </Modal>
      </View>
    </View>
  );
};

const styles = StyleSheet.create({
  centeredView: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    marginTop: 22,
  },
  modalView: {
    margin: 20,
    backgroundColor: 'white',
    borderRadius: 20,
    width:300,
    padding: 35,
    alignItems: 'center',
    shadowColor: '#000',
    shadowOffset: {
      width: 0,
      height: 2,
    },
    shadowOpacity: 0.25,
    shadowRadius: 4,
    elevation: 5,
  },
  button: {
    borderRadius: 20,
    padding: 10,
    elevation: 2,
  },
  buttonOpen: {
    backgroundColor: '#F194FF',
  },
  buttonClose: {
    backgroundColor: '#2196F3',
  },
  textStyle: {
    color: 'white',
    fontWeight: 'bold',
    textAlign: 'center',
  },
  modalText: {
    marginBottom: 15,
    textAlign: 'center',
  },
});
```
特徴はAlertやDialogと違い、ほぼほぼスタイリングで自分で実装しているところです。
よくも悪くも自分の理想のものを作ることができます。

UIはこんな感じになります。
![スクリーンショット 2021-09-08 18.57.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1812049/81a96432-4e19-07fb-a3f1-94d462754a81.png)
表示方法はDialogと同様にtrueの時は表示、falseで非表示としています。

ボタンをタップした時、モーダルは下から出てきます。
これはModalタグ内のanimatedTypeで設定しています。
現在はslideにしていますが、noneにすることでAlertやDialogと同じような感じで表示されます。

二つ目のtransparentはtrueかfalseで設定します。
trueの場合：モーダルを出した時に背景をもともと設定している色のままにする
falseの場合：モーダルを出すときは背景色を決めていても画面全体を真っ白にする

modal内はViewタグを使って一からスタイリングしているため、自分の思うようなものを作ることができますが、AlertやDialogに比べてめんどくさいです。
## Modalの特徴
１、UIは自分で一から構築
２、自由度は高いがAlertやDialogに比べて実装がめんどくさい。

# 結論
以上三つの似たUIを作ってみましたが、僕的にはDialogが一番使いやすいと思いました。
ただ、OKとキャンセルを出すだけだったらAlertで十分です。
Modalは使うことはないかなと思いました。Dialogを使えばやりたいことはできると思いますので。
#### ぜひ参考にしてください！