react-moodalを使ってモーダル機能を実装する

react-modalというライブラリを使用して、
下記のようなモーダルを実装しました。
https://github.com/diasbruno/react-modal
https://reactcommunity.org/react-modal/


![m.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1559434/27738bf3-682e-80ea-7920-2ab5953fd815.gif)


## 使い方
```
npm install react-modal
```

Modalコンポーネントをimportして使用する。
```components/SampleModal.jsx
import Modal from 'react-modal';
import { useState } from 'react';

const customStyles = {
  content: {
    top: '50%',
    left: '50%',
    right: 'auto',
    bottom: 'auto',
    marginRight: '-50%',
    transform: 'translate(-50%, -50%)',
  },
};

function SampleModal() {
  let subtitle;
  const [modalIsOpen, setIsOpen] = useState(false);

  function openModal() {
    setIsOpen(true);
  }

  function afterOpenModal() {
    // references are now sync'd and can be accessed.
    subtitle.style.color = '#f00';
  }

  function closeModal() {
    setIsOpen(false);
  }

  return (
    <div>
      <button onClick={openModal}>Open Modal</button>
      <Modal
        isOpen={modalIsOpen}
        onAfterOpen={afterOpenModal}
        onRequestClose={closeModal}
        style={customStyles}
        contentLabel="Example Modal"
      >
        <h2 ref={(_subtitle) => (subtitle = _subtitle)}>Hello</h2>
        <button onClick={closeModal}>close</button>
        <div>I am a modal</div>
        <form>
          <input />
          <button>tab navigation</button>
          <button>stays</button>
          <button>inside</button>
          <button>the modal</button>
        </form>
      </Modal>
    </div>
  );
}

export default SampleModal;

```


## 応用：画面内に複数のモーダルを実装する

下記の記事を参考に1画面に複数のモーダルを実装しました。

https://zenn.dev/cryptobox/articles/ace08cae85e3a2


![ｍ２.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1559434/a9836630-f9af-5652-aa79-d43499c70feb.gif)


openModalファンクションに選択したモーダルの番号を渡すように修正。

また、isOpenの条件（モーダルを開く条件）を修正。
　旧：modalIsOpenのstateがTRUEの時モーダルを開く。
　新：押下したモーダルの番号に対応したモーダルを開く。


```jsx
import Modal from 'react-modal';
import { useState } from 'react';

const customStyles = {
  overlay: {
    position: "fixed",
    top: 0,
    left: 0,
    backgroundColor: "rgba(0,0,0,0.60)"
  },
  content: {
    height: '70%',
    width: '60%',
    top: '50%',
    left: '50%',
    right: 'auto',
    bottom: 'auto',
    marginRight: '-50%',
    transform: 'translate(-50%, -50%)',
  },
};

function SampleModal() {
  let subtitle;

  const ModalList = ['モーダル１', 'モーダル２', 'モーダル３']
  const [selectedItem, setSelectedItem] = useState('')

  function openModal(name) {
    setSelectedItem(name)
  }

  function afterOpenModal() {
    // references are now sync'd and can be accessed.
    subtitle.style.color = '#f00';
  }

  function closeModal() {
    setSelectedItem(false)
  }

  return (
    <>
      {
        ModalList.map((item) => {
          return (
            <>
              <button onClick={() => { openModal(item) }}>{item}</button>
              <Modal
                isOpen={item === selectedItem}
                onAfterOpen={afterOpenModal}
                onRequestClose={closeModal}
                style={customStyles}
                contentLabel="Example Modal"
              >
                <h2 ref={(_subtitle) => (subtitle = _subtitle)}>Hello Modal{item}</h2>
                <button onClick={closeModal}>close</button>
                <div>{selectedItem}</div>
                <form>
                  <input />
                </form>
              </Modal>
            </>
          )
        })
      }
    </>
  )
}

export default SampleModal;


```