Author avatar

Marques Woodson

Working with Bootstrap's Modals in React

Marques Woodson

  • Nov 26, 2019
  • 11 Min read
  • 47 Views
  • Nov 26, 2019
  • 11 Min read
  • 47 Views
Web Development
React

Introduction

Modals are very common in front-end applications. React-bootstrap has rebuilt the jQuery-based modal with React components that provide the same functionality as the jQuery counter-parts. In this guide I will show you how to install react-bootstrap, show and hide a modal, work with different modal events, and customize the modal to your needs using Bootstrap Modals in React. Let's get started.

Installing React-Bootstrap

To get started with using Bootstrap in your React application, you need to install the react-bootstrap package from npm along with the bootstrap v4 package. You will need to install regular Bootstrap for the CSS.

1
2
3
yarn add react-bootstrap bootstrap
# or
npm i react-bootstrap bootstrap
bash

After the installation is complete, you can import the modal component and the styling into your module.

1
2
import Modal from "react-bootstrap/Modal";
import "bootstrap/dist/css/bootstrap.min.css";
js

A modal has a few basic sections: the Header, the Title, the Body, and the Footer. These sections will hold the content that we need to display. Here's an example displaying a basic modal using these components.

1
2
3
4
5
6
7
8
9
10
11
12
import Modal from "react-bootstrap/Modal";
import "bootstrap/dist/css/bootstrap.min.css";

const App = () => {
  return (
    <Modal show={true}>
      <Modal.Header>Hi</Modal.Header>
      <Modal.Body>asdfasdf</Modal.Body>
      <Modal.Footer>This is the footer</Modal.Footer>
    </Modal>
  );
};
js

Use Modal.<component> syntax to display each component. If you would prefer not to use the object literal syntax when defining you modals, you can import each component separately as well.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import React from "react";
import ReactDOM from "react-dom";
import Modal from "react-bootstrap/Modal";
import ModalBody from "react-bootstrap/ModalBody";
import ModalHeader from "react-bootstrap/ModalHeader";
import ModalFooter from "react-bootstrap/ModalFooter";
import ModalTitle from "react-bootstrap/ModalTitle";

const App = () => {
  return (
    <Modal show={true}>
      <ModalHeader>
        <ModalTitle>Hi</ModalTitle>
      </ModalHeader>
      <ModalBody>asdfasdf</ModalBody>
      <ModalFooter>This is the footer</ModalFooter>
    </Modal>
  );
};
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
js

Now that you have a functional modal in your application, let's make the modal interactive.

Hiding/Showing a Modal

Our previous example shows how to display a modal using show property on the modal component. I initially hard-coded the value to true, but it is not very flexible. To improve this, let's set the value to a variable or a toggle-able expression. We will also create a button to toggle the visibility.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
const App = () => {
  const [isOpen, setIsOpen] = React.useState(false);

  const showModal = () => {
    setIsOpen(true);
  };

  const hideModal = () => {
    setIsOpen(false);
  };

  return (
    <>
      <button onClick={showModal}>Display Modal</button>
      <Modal show={isOpen} onHide={hideModal}>
        <Modal.Header>
          <Modal.Title>Hi</Modal.Title>
        </Modal.Header>
        <Modal.Body>The body</Modal.Body>
        <Modal.Footer>
          <button onClick={hideModal}>Cancel</button>
          <button>Save</button>
        </Modal.Footer>
      </Modal>
    </>
  );
};
js

I've added a showModal and hideModal method to update a state property called isOpen. Assigning the isOpen variable as the value to the show property means we now have control over whether the modal is showing or not. The new onHide property is necessary if we want to hide the modal when clicking on the non-static backdrop or hitting the esc key. I've also added a couple of buttons to the footer to make this modal more realistic. In addition to hiding the Modal by hitting the "Esc" key or clicking the backdrop, I put the hideModal method on the Cancel button to show a different way of hiding the modal.

Modal Events

The modal comes with some helpful events to assist us with the intermediate states between hiding and showing the modal. For example, if you want to show different content in your modal, on the main page as it's loading into view, or in the process of hiding, then you can utilize the onEnter, onEntered, onExit or onExited callbacks respectively. Let's look at these callbacks individually in greater depth.

onEntered

The onEntered event takes a callback that will fire once the modal has finished coming into view. This is useful if we want to asynchronously load data into the modal, or interact with elements once they are visible in the modal. In this example, let's update the title of our modal from Transitioning... to Modal Ready.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
const App = () => {
  const [isOpen, setIsOpen] = React.useState(false);
  const [title, setTitle] = React.useState("Transitioning...");

  const showModal = () => {
    setIsOpen(true);
  };

  const hideModal = () => {
    setIsOpen(false);
    setTitle("Transitioning...");
  };

  const modalLoaded = () => {
    setTitle("Modal Ready");
  };

  return (
    <>
      <button onClick={showModal}>Display Modal</button>
      <Modal show={isOpen} onHide={hideModal} onEntered={modalLoaded}>
        <Modal.Header>
          <Modal.Title>{title}</Modal.Title>
        </Modal.Header>
        <Modal.Body>The body</Modal.Body>
        <Modal.Footer>
          <button onClick={hideModal}>Cancel</button>
          <button>Save</button>
        </Modal.Footer>
      </Modal>
    </>
  );
};
js

onEnter

In this example, we'll start a timer to count how long it takes to open the modal in milliseconds. We'll display in the modal's body how long it takes for the onEnter callback to get the command to start opening the modal to when it finishes opening the modal.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
const App = () => {
  const [isOpen, setIsOpen] = React.useState(false);
  const [timer, setTimer] = React.useState(0);
  const [startTime, setStartTime] = React.useState(0);
  const [endTime, setEndTime] = React.useState(0);

  const showModal = () => {
    setIsOpen(true);
  };

  const hideModal = () => {
    setIsOpen(false);
    setTitle("Transitioning...");
  };

  const startTimer = () => {
    setStartTime(Date.now());
  };

  const modalLoaded = () => {
    setEndTime(Date.now());
  };

  return (
    <>
      <button onClick={showModal}>Display Modal</button>
      <Modal
        show={isOpen}
        onHide={hideModal}
        onEnter={startTimer}
        onEntered={modalLoaded}
      >
        <Modal.Header>
          <Modal.Title>{title}</Modal.Title>
        </Modal.Header>
        <Modal.Body>{endTime - startTime} ms</Modal.Body>
        <Modal.Footer>
          <button onClick={hideModal}>Cancel</button>
          <button>Save</button>
        </Modal.Footer>
      </Modal>
    </>
  );
};
js

onExit and onExited

We can similarly utilize the onExit and onExited callbacks to handle page interactions during the transition. Let's show a 'goodbye' message when the user closes the modal. We'll also change the page background when the modal is finished exiting.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
const App = () => {
  const [isOpen, setIsOpen] = React.useState(false);
  const [timer, setTimer] = React.useState(0);
  const [startTime, setStartTime] = React.useState(0);
  const [endTime, setEndTime] = React.useState(0);

  const showModal = () => {
    setIsOpen(true);
    setTitle("Modal Ready");
    document.body.style.backgroundColor = "white";
  };

  const hideModal = () => {
    setIsOpen(false);
  };

  const startTimer = () => {
    setStartTime(Date.now());
  };

  const modalLoaded = () => {
    setEndTime(Date.now());
  };

  const onExit = () => {
    setTitle("Goodbye 😀");
  };

  const onExited = () => {
    document.body.style.backgroundColor = "green";
  };

  return (
    <>
      <button onClick={showModal}>Display Modal</button>
      <Modal
        show={isOpen}
        onHide={hideModal}
        onEnter={startTimer}
        onEntered={modalLoaded}
        onExit={onExit}
        onExited={onExited}
      >
        <Modal.Header>
          <Modal.Title>{title}</Modal.Title>
        </Modal.Header>
        <Modal.Body>{endTime - startTime} ms</Modal.Body>
        <Modal.Footer>
          <button onClick={hideModal}>Cancel</button>
          <button>Save</button>
        </Modal.Footer>
      </Modal>
    </>
  );
};
js

Customizing the Modal

Making the modal match your brand and design is simple. Use the same methods available for any react component to style a modal, including any CSS-in-js solution, standard CSS, and CSS Modules. If you need to add a class to the modal dialog, use the dialogClassName property.

1
2
3
4
5
6
7
8
9
10
11
const App = () => {
  return (
    <Modal show={true} dialogClassName={"primaryModal"}>
      <ModalHeader>
        <ModalTitle>Hi</ModalTitle>
      </ModalHeader>
      <ModalBody>asdfasdf</ModalBody>
      <ModalFooter>This is the footer</ModalFooter>
    </Modal>
  );
};
js

In the above example, the .primaryModal class will be added to the modal dialog div.

as property

The default HTML element for a modal component container is the div element. If you do not want to use the div default, you can specify a different element with the as property. This works for not just the modal dialog, but also for the header, title, body, and footer.

1
2
3
4
5
6
7
8
9
10
11
const App = () => {
  return (
    <Modal show={true} as="section">
      <ModalHeader as="span">
        <ModalTitle as="h4">Hi</ModalTitle>
      </ModalHeader>
      <ModalBody as="section">asdfasdf</ModalBody>
      <ModalFooter as="footer">This is the footer</ModalFooter>
    </Modal>
  );
};
js

Sizing

The size property on the <Modal> component can be used to set the width of the modal to the defaults defined in the bootstrap CSS. There are three options: sm, lg, xl. If you want to define your own custom class to set the width, you can do that as well.

1
2
3
4
5
6
7
8
9
10
11
const App = () => {
  return (
    <Modal show={true} size="lg">
      <ModalHeader>
        <ModalTitle>Hi</ModalTitle>
      </ModalHeader>
      <ModalBody>asdfasdf</ModalBody>
      <ModalFooter>This is the footer</ModalFooter>
    </Modal>
  );
};
js

Conclusion

Working with the react-bootstrap component library allows you the benefits of Bootstrap and React in one tool. And, if you already know how to use React components and properties, then you immediately start working with Bootstrap. After reading this guide, you should be able to:

  • add react-bootstrap and bootstrap to your project
  • show and hide a modal
  • work with built-in modal events
  • and customize the modal to fit your brand.

Please keep an eye out for more guides, where I will show you how to use bootstrap components within a react application. Thanks for reading 😃

For more details about styling react components, check out the course Styling React Components by Jake Trent. This guide will introduce you to react-bootstrap.

0