How to get a React Bootstrap Modal to open and close using a button of your choice in a parent component

Sharad Satsangi
Nerd For Tech
Published in
4 min readMay 4, 2021

I was working on a site with some friends last week. We were using React-Bootstrap as a solution for out-of-the-box UI components. We all liked the idea of using modals for our pop-up menus and we wanted to use side tabs for navigation. The way the React-Bootstrap modal component is written, the button to open the modal is contained within the component itself. This can make things confusing if you’re trying to figure out how to place the component. If you’re familiar with React-Bootstrap and you’re just searching for the solution in a hurry, skip down to the picture of a stop sign to see my solution for this problem. If you’d like to read a little more about this problem, read on.

Confused? Let’s unpack this!

Start here if you don’t know about React-Bootstrap

React-Bootstrap is a front-end framework of components for react. If you use React and haven’t checked out React-Bootstrap, it’s worth the effort to get acquainted with it. It’s pretty easy to implement, you can follow the walk-through on their site here. I’ve never run into any problems getting React-Bootstrap working with my apps.

To install React-Bootstrap, use npm:

npm install react-bootstrap bootstrap

Select the components you’d like to use from their site and then, in your code, import each component you plan on using individually. In the case of the Modal:

import Modal from 'react-bootstrap/Modal'

or

import { Modal } from 'react-bootstrap';

In the documentation for each component, you’ll see sample implementation code for the components. These take the import libraries and build a lot of functionality for you to use. I think this is what makes React-Bootstrap so popular and powerful. Pick the code that’s closest to the functionality you want for a component and use it as a starting point for your implementation of the component. For the purposes of this post, let’s use the code for the Live Demo Modal:

Pictured, the Live Demo Modal. The “Launch Demo Modal” button, also part of the code, opens it
import Modal from 'react-bootstrap/Modal'function Example() {
const [show, setShow] = useState(false);
const handleClose = () => setShow(false);
const handleShow = () => setShow(true);
return (
<>
<Button variant="primary" onClick={handleShow}>
Launch demo modal
</Button>
<Modal show={show} onHide={handleClose}>
<Modal.Header closeButton>
<Modal.Title>Modal heading</Modal.Title>
</Modal.Header>
<Modal.Body>Woohoo, you're reading this text in a modal!</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={handleClose}>
Close
</Button>
<Button variant="primary" onClick={handleClose}>
Save Changes
</Button>
</Modal.Footer>
</Modal>
</>
);
}
render(<Example />);

… so now we have a component, Example, that imports the Modal functionality from React Bootstrap and contains the sample code from the component as presented on the React-Bootstrap website. The code to open the Modal are the 3 lines right after the return:

<Button variant="primary" onClick={handleShow}>
Launch demo modal
</Button>

… this places a button where we place Example in our app, and when we click it, we set show in the Modal’s state to true via the setState hook. There are a couple of buttons in the sample code to close the Modal, they both have the onClick={handleClose} to set show back to false. The behaviors are set in the Modal tag:

<Modal show={show} onHide={handleClose}>

This works great, but it’s self-contained. The button is part of the Modal code. What if we want to open the modal from React-Bootstrap’s Tab component?

The Tab component

The type of Tabs we’re working with in the code below
<Tab.Container id="left-tabs-example" defaultActiveKey="first">
<Row>
<Col sm={3}>
<Nav variant="pills" className="flex-column">
<Nav.Item>
<Nav.Link eventKey="first">Tab 1</Nav.Link>
</Nav.Item>
<Nav.Item>
<Nav.Link eventKey="second">Tab 2</Nav.Link>
</Nav.Item>
</Nav>
</Col>
<Col sm={9}>
<Tab.Content>
<Tab.Pane eventKey="first">
<Sonnet />
</Tab.Pane>
<Tab.Pane eventKey="second">
<Sonnet />
</Tab.Pane>
</Tab.Content>
</Col>
</Row>
</Tab.Container>

Just like in the picture abovce, the code sets up Tabs for navigation. Each <NavItem> in the <Nav> section corresponds to a <Tab.Pane> in the <Tab.Content> portion of the code. The goal here is to place our <Example> Modal in such a way that we can open it up from a Tab.

Ok, we’re through with the background, here’s the solution

Here’s what you need to know to get the Modal to open up with the Tab click

All you need to do to get the Modal to open up as desired it to move the show hook, up from the Modal, <Example>, to Tab. Once show and is in Tab, you can pass it and its setState hook down as props to the Modal. So, in Tab:

const [modalShow, setModalShow] = useState(false);

and in the Nav section:

<Nav.Link
className="tab__link"
eventKey="modal"
onClick={() => setModalShow(true)}>

Show the Modal!
</Nav.Link>

and in it’s corresponding Tab:

<Tab.Pane eventKey="second"><Example
modalShow={modalShow}
setModalShow={setModalShow}/>
</Tab.Pane>

Note that we’re using setModalShowdirectly and eliminating functionshandleClose, and handleOpen.

In the Example Modal, we need to make a few changes. First change:

<Modal show={show} onHide={handleClose}>

to:

<Modal show={props.moadalShow}>

And replace both onClick={handleClose} with onClick={props.setModalShow(false)} . Remove the code for the opening button, and also remove the functions handleOpen and handleClose, and you’re all set.

Now, when a user clicks the Tab marked Show the Modal!, they’ll open up the Modal, and when they click the x or close buttons on the component the Modal will close. Easy-peasy.

React-Bootstrap is one of many custom frameworks freely available to power-up our frontend development needs. This strategy of moving data to a higher component and passing it down to the component it controls, comes in handy a often and is worth getting familiar with just as much as the React-Bootstrap framework. Have an awesome week and happy coding!

--

--