Search code examples
bootstrap-modalreact-bootstrapuse-statebootstrap-5dry

How to properly set state to allow React Bootstrap Modal to work on mapped data?


Trying to build a D.R.Y. list of vocabulary terms with React Bootstrap (v.2.2.3) using Bootstrap 5.1.

I bring in my data:

import vocData from '../data/vocData'

My component:

const VocList = () => {
  const [show, setShow] = useState(false)

  const handleClose = () => setShow(false)

  return (
    <ul className="list-inline">
      {Object.keys(vocData).map((item, key) => (
        <React.Fragment key={key}>
          <li className="list-inline-item voc-item">
            <Button>
              <small>{vocData[item].title}</small>
            </Button>
          </li>

          <Modal
            show={show}
            onHide={handleClose}
            backdrop="static"
            keyboard={false}
            aria-labelledby={`contained-modal-title-${vocData[item].href}`}
            centered
          >
            <Modal.Header closeButton>
              <Modal.Title id={`contained-modal-title-${vocData[item].href}`}>
                {vocData[item].title}
              </Modal.Title>
            </Modal.Header>
            <Modal.Body>{vocData[item].content}</Modal.Body>
          </Modal>
        </React.Fragment>
      ))}
    </ul>
  )
}

I can see my list of vocabulary terms is working but my modal is not appearing when I click the button. I've tried to research and read through:

but I'm unable to find an answer.

How can I dynamically setState and be able to render my modal for that vocabulary term in my list?


Solution

  • Try to use Modal only once and not render it many times. You can show only one Modal at time anyway. I have created a subcomponent for clarity.

    There are many ways how to play with state. Here the initial state is null and hides the modal. When we click on button we set state with one vocData entry. This also toggles the visibility of Modal.

    Finally, when we close its again, we set our state to null. In this way we use one state for two purposes - control vision and rendering of Modal and holding data for it.

    Sandbox