bootstrap
bootstrap copied to clipboard
Bug with Bootstrap Collapse in combination with Bootstrap Toast - ReactJS
Hi,
I think I may have found a bug between the Bootstrap v5.1.3 collapse feature and Toast-Messages in ReactJS
Setup to replicate the error:
Create a default react project with:
npx create-react-app collapse-toast-test- Import boostrap with
npm i bootstraporyarn i bootstrap - In
index.jsimport bootstrap:
import 'bootstrap/dist/css/bootstrap.css';
import 'bootstrap/dist/js/bootstrap.bundle.js';
- Use buttons from example: https://getbootstrap.com/docs/5.1/components/collapse/ and paste the code into
app.js - In
app.jsimport Toast (and make use of it if you want)
import { Toast } from "bootstrap";
Result:
Pressing the buttons only shows the hidden elements. Hide afterwards is not working. So the toggle-feature is bugged.
Used versions:
React-Version: 18.0.0 Bootstrap-Version: 5.1.3
Perhaps duplicate of #35665?
Maybe. But this problem is a little bit different. The collapse is working fine without importing Toast. So "hide" and "show" on collapse is no problem without Toast. Just the combination of both collapse and Toast is causing the issue.
Any help of React devs, would be handy here
Would you be interested in using react-bootstrap? You still use the Bootstrap stylesheet, but the components have been re-written and optimized for React. As mentioned in #35665 there are compatibility issues that you have to be mindful of when using vanilla JS from Bootstrap.
The bug you are seeing has nothing to do with React, and almost nothing to do with bootstrap either. Rather, it's your improper import of bootstraps javascript. You are explicitly importing bootstrap's umd file (bundled with popper... but that irrelevant here), then importing the Toast class from bootstraps default path... which in the case of the bundler in create-react-app is going to be the module path, ie bootstraps esm file. This effectively loads certain parts of bootstraps code base twice and you are seeing the effects of this.
So instead of
import 'bootstrap/dist/css/bootstrap.css';
import 'bootstrap/dist/js/bootstrap.bundle.js';
// and later
import { Toast } from "bootstrap";
You'll want
import 'bootstrap/dist/css/bootstrap.css';
import 'bootstrap';
// and later
import { Toast } from "bootstrap";
The import 'bootstrap'; is equivalent to import 'bootstrap/dist/js/bootstrap.esm'; in this case - though I would not recommend the long hand import. Use the default and let your bundler decide what kind of files it wants.
Note: You will need to make sure popper is installed as well - as you would no longer be loading the "bootstrap bundle" file that included everything in 1 file.
Hello there!
- First, notice you imported the compiled bundle of Bootstrap. Then, you want to use the ESM version of bootstrap in the same project. This confuses the module bundler of Create React App which is Webpack.
- Read about using Bootstrap with Webpack module bundler (included in Create React App) here
- I got the same issue with collapse (in the navbar component) and tooltips using React. I solved in the following way:
3.1 Importing only the CSS file in the index.js file or the App.js file and not importing the bundle JS file.
// ...
import "bootstrap/dist/css/bootstrap.min.css";
// ...
3.2 I am using the collapse feature in my navbar component. I am not importing bootstrap in this file (Navbar.jsx) only configuring the HTML attributes, like the following code:
<!-- ... -->
<button
className="navbar-toggler"
type="button"
data-bs-toggle="collapse"
data-bs-target="#navbarMenuContent"
aria-expanded="false"
aria-controls="navbarMenuContent"
aria-label="Toggle navigation"
>
<span className="navbar-toggler-icon"></span>
</button>
<div className="collapse navbar-collapse" id="navbarMenuContent">
<ul className="navbar-nav me-auto mb-2 mb-lg-0">
<!-- ... -->
</ul>
</div>
<!-- ... -->
3.3 Then, I am using the Tooltip feature like this (here I am importing bootstrap ESM and the Webpack module bundler bundles correctly):
// ...
import { Tooltip } from "bootstrap";
// ...
const enableTooltip = (someHtmlElement) => {
new Tooltip(someHtmlElement);
};
// ...
I used this to make the Collapse feature and the tooltip component work correctly together in the same project. You can try this way to use Bootstrap + React.
Additional Notes:
- Bootstrap v5.2.0
- React v18.2.0
- React Scripts: v5.0.1
- Notice in your "node_modules" folder that PopperJS (Bootstrap's peer dependency) is installed when you install bootstrap.
Another workaround is to import Toast directly from toast.js
import Toast from 'bootstrap/js/dist/toast.js';