DEV Community

loading...
Cover image for Using Bootstrap 5 with React
Codeply

Using Bootstrap 5 with React

carolskelly profile image Carol Skelly ・Updated on ・2 min read

How to use the new Bootstrap 5 with React

Bootstrap and React have both been around for a while now, but now that the Bootstrap 5 beta is out, there's finally something to cheer about! πŸ™Œ

Now that Bootstrap 5 no longer requires jQuery, using it in your React app is much easier and without conflicts! 😲 Now that Bootstrap 5 components are written as vanilla JS plugins, you get improved alignment with React's best patterns & practices.

This also means it's possible to use Bootstrap 5 components without the need for a 3rd party library like react-bootstrap or reactstrap.


First up, add Bootstrap to your React app's package.json:

npm install bootstrap --save

Once Bootstrap is included, you'll be able to import components the way you do with any JS module. For example, let's import Bootstrap's Toast component...

import { Toast} from bootstrap

And then use it with React's useEffect and useState hooks...

function ToastDemo() {
    var [toast, setToast] = useState(false);
    const toastRef = useRef();

    useEffect(() => {
        var myToast = toastRef.current
        var bsToast = bootstrap.Toast.getInstance(myToast)

        if (!bsToast) {
            // initialize Toast
            bsToast = new Toast(myToast, {autohide: false})
            // hide after init
            bsToast.hide()
            setToast(false)
        }
        else{
            // toggle
            toast ? bsToast.show() : bsToast.hide()

        }
    })

    return (
    <div className="py-2">
        <button className="btn btn-success" onClick={() => setToast(toast => !toast)}>
            Toast {toast?'hide':'show'}
        </button>
        <div className="toast" role="alert" ref={toastRef}>
            <div className="toast-header">
                <strong className="me-auto">Bootstrap 5</strong>
                <small>4 mins ago</small>
                <button type="button" className="btn-close" onClick={() => setToast(false)} aria-label="Close"></button>
            </div>
            <div className="toast-body">
              Hello, world! This is a toast message.
            </div>
        </div>
    </div>
    )
}
Enter fullscreen mode Exit fullscreen mode

Or, (if that wasn't easy enough) use the new namespaced data-bs- attributes directly in your markup. For example, let's use the Bootstrap 5 Collapse component...

function CollapseDemo() {
  return (
    <div className="py-2">
        <button className="btn btn-primary" data-bs-target="#collapseTarget" data-bs-toggle="collapse">
            Toggle collapse
        </button>
        <div className="collapse" id="collapseTarget">
            This is the toggle-able content!
        </div>
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode

Now you can easily use any of the Bootstrap 5 Components in your React project. Check out these Bootstrap 5 React examples that use the Bootstrap 5 Toast, Alert, Collapse, Modal, Tooltip and Popover. Also be sure to take a look at all the new updates in Bootstrap 5.

What do you think? Do you plan on bringing Bootstrap 5 into your next React project, or do you prefer a different React friendly design system?

Discussion (6)

pic
Editor guide
Collapse
joelnwalkley profile image
Joel N. Walkley

Aren't we supposed to avoid direct interaction with the DOM in a React app? Your useState targets the element directly by name; and also directly adds an event listener. Is there another way to make use of Bootstrap without the 3rd party libraries?

Collapse
carolskelly profile image
Carol Skelly Author

This is a great question and you're absolutely right! As explained in the React hooks FAQ you'd want useRef in this case. This will ensure we get the .current instance of the DOM element that's synched with the React lifecycle. I've updated the Toast example accordingly...

function ToastDemo() {
    var [toast, setToast] = useState(false);
    const toastRef = useRef();

    useEffect(() => {
        var myToast = toastRef.current
        var bsToast = bootstrap.Toast.getInstance(myToast)

        if (!bsToast) {
            // initialize Toast
            bsToast = new Toast(myToast, {autohide: false})
            // hide after init
            bsToast.hide()
            setToast(false)
        }
        else{
            // toggle
            toast ? bsToast.show() : bsToast.hide()

        }
    })

    return (
    <div className="py-2">
        <button className="btn btn-success" onClick={() => setToast(toast => !toast)}>
            Toast {toast?'hide':'show'}
        </button>
        <div className="toast" role="alert" ref={toastRef}>
            <div className="toast-header">
                <strong className="me-auto">Bootstrap 5</strong>
                <small>4 mins ago</small>
                <button type="button" className="btn-close" onClick={() => setToast(false)} aria-label="Close"></button>
            </div>
            <div className="toast-body">
              ...
            </div>
        </div>
    </div>
    )
}
Enter fullscreen mode Exit fullscreen mode

I also updated the other examples to follow this same pattern.

Collapse
ruben profile image
Ruben Santana

For those who are struggling with the navbar and the toggler, here is a good example. dev.to/johnotu/how-to-toggle-boots...

Collapse
omrisama profile image
Omri Gabay

So does this make Reactstrap and React Bootstrap obsolete?

Collapse
carolskelly profile image
Carol Skelly Author

I don't think so, it just makes it possible to use Bootstrap in React in a way that aligns with React patterns/practices.

Collapse
amitavroy7 profile image
Amitav Roy

Yes, as Joel rightly pointed out what you have done - is it the right way to do things in React?