Reputation: 555
I am making my first bootstrap modal in react but I'm struggling with it. I have the below component which is imported into my application's navbar. When I click the anchor tag in the below component, it will toggle the modal's html elements rendering in the DOM. However these elements are not visible.
I am trying to use regular bootstrap instead of react-strap, because I have limited experience with React-strap and am trying to avoid learning a new package. Is this doable with regular bootstrap in React?
So far I have tried a few fixes, one of which is to remove ternary operator in my render function, and then add data-toggle and data-target attributes to my anchor tag. However, this has not worked for me.
import React, { Component } from 'react'
export default class RegisterModal extends Component {
state={
modal: false
}
toggle = (e) => {
e.preventDefault();
this.setState(
{modal: !this.state.modal}
)
}
render() {
return (
<div>
<a href='' className="nav-link" onClick={this.toggle} >Register</a>
{ this.state.toggle? <div id="registerModal" className="modal" tabindex="-1" role="dialog">
<div className="modal-dailog" role = "document">
<div className="modal-content">
<div className="modal-header">
<h5 className="modal-title">Register</h5>
<button className="close" type='button' data-dismiss="modal" aria-label='Close'>
<span aria-hidden='true'>×</span>
</button>
</div>
<div className="modal-body">
<p>filler text</p>
</div>
</div>
</div>
</div> : null}
</div>
)
}
}
Edit: I should also note I am bringing in bootstrap by importing it into my index.js file. Is there a way I should be importing the Jquery aspect of bootstrap with this setup?
import App from './App';
import "bootstrap/dist/css/bootstrap.min.css"
import './App.css';
import reportWebVitals from './reportWebVitals';
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
Upvotes: 1
Views: 841
Reputation: 1267
Bootstrap alone using DOM to display or hide the dialog, so in order for it to work it has to link between the button
or a
and the dialog target. You are using React state to display/hide, which may not create the desired result. Below is the code that work
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModal">
Launch demo modal
</button>
<!-- Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
...
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
The important property that link between a button/link
in this case is the data-target
and not the React state. You can, still, add the event listener to the button.
One note is that this may fix your issue, but in the future try to avoid this problem by using either react-bootstrap
or reactstrap
as it integrate React state management with bootstrap and this will help you a lot later. They also not much different from Boostrap itself. For your reference this is what you code may look like with react-bootstrap
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>
</>
);
}
Upvotes: 2