bootstrap icon indicating copy to clipboard operation
bootstrap copied to clipboard

Bug with Bootstrap Collapse in combination with Bootstrap Toast - ReactJS

Open Prime1Code opened this issue 3 years ago • 7 comments

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 bootstrap or yarn i bootstrap
  • In index.js import bootstrap:
import 'bootstrap/dist/css/bootstrap.css';
import 'bootstrap/dist/js/bootstrap.bundle.js';
  1. Use buttons from example: https://getbootstrap.com/docs/5.1/components/collapse/ and paste the code into app.js
  2. In app.js import 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

Prime1Code avatar Apr 25 '22 19:04 Prime1Code

Perhaps duplicate of #35665?

mdo avatar Apr 29 '22 16:04 mdo

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.

Prime1Code avatar May 01 '22 06:05 Prime1Code

Any help of React devs, would be handy here

GeoSot avatar May 03 '22 22:05 GeoSot

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.

kyletsang avatar May 05 '22 21:05 kyletsang

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.

RyanBerliner avatar May 17 '22 00:05 RyanBerliner

Hello there!

  1. 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.
  2. Read about using Bootstrap with Webpack module bundler (included in Create React App) here
  3. 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.

axelsomerseth avatar Sep 01 '22 05:09 axelsomerseth

Another workaround is to import Toast directly from toast.js

import Toast from 'bootstrap/js/dist/toast.js';

victory-sokolov avatar Sep 21 '22 10:09 victory-sokolov