François Richard
François Richard

Reputation: 7035

Bootstrap collapse with react js

Hi I'm trying to use bootstrap collapse inside a react view and it's not working. It's very simple but I don't understand what's going on.

return (<div>
    <button className="btn" type="button" data-toggle="collapse" data-target="#collapseExample" aria-expanded="true" aria-controls="collapseExample">
        ButtonClickthis!
    </button>
    <div className="collapse" id="collapseExample">
        <div className="well">
            ...blablablacontent
        </div>
    </div>
</div>);

Upvotes: 23

Views: 42839

Answers (6)

silencedogood
silencedogood

Reputation: 3299

Figured I'd add an update here. With the updated version of React, not only do you not need vanilla code such as document.getElementById(), but you don't need refs either, or jQuery for that matter. You can simply import collapse like so:

import Collapse from 'react-bootstrap/Collapse'

The collapse transition can be accomplished very easily with this component, as shown in the docs. Here's the code pulled from the same:

const {useState} = React;

const Example = () => {

  const [toggle, setToggle] = useState(false);
  const toggleFunc = React.useCallback(() => setToggle(!toggle));

  return (
    <div>
      <button onClick={toggleFunc}>Toggle Collapse</button>
      <ReactBootstrap.Collapse in={toggle}>
          <div>
             Stuff to collapse
          </div>
      </ReactBootstrap.Collapse>
    </div>
  );
};

// Render it
ReactDOM.render(
  <Example />,
  document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/react-bootstrap@next/dist/react-bootstrap.min.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<div id="react"></div>

** Note: Obviously this code was modified to work with code snippets here on SO. If you're working in your local environment, use the code from the docs, which is even cleaner.

Upvotes: 3

Carol Skelly
Carol Skelly

Reputation: 362320

Bootstrap 5 no longer requires jQuery which makes it easier to use with React. For example, here's the Bootstrap Collapse component using the React useState, useEffect hooks:

import { useState, useEffect } from React
import { Collapse } from bootstrap

function CollapseDemo() {
    var [toggle, setToggle] = useState(false);
    
    useEffect(() => {
        var myCollapse = document.getElementById('collapseTarget')
        var bsCollapse = new Collapse(myCollapse, {toggle: false})
        toggle ? bsCollapse.show() : bsCollapse.hide()
    })

  return (
    <div className="py-2">
        <button className="btn btn-primary" onClick={() => setToggle(toggle => !toggle)}>
            Toggle collapse
        </button>
        <div className="collapse" id="collapseTarget">
            This is the collapsible content!
        </div>
    </div>
  )
}

Demo

Upvotes: 11

Davi Lago
Davi Lago

Reputation: 50

Install the module with npm

npm install react-bootstrap bootstrap

And import in your component

import 'bootstrap/dist/css/bootstrap.min.css';

import 'bootstrap/dist/js/bootstrap.min.js';

This work for me

Upvotes: 0

Mateus Ferreira
Mateus Ferreira

Reputation: 529

If you don't want to mess around with jQuery:

First, build a ref object for each of your collapsible elements; also build a function to toggle the .show CSS class to the corresponding element.

Then, use toggler function in a button onClick.

class Collapse extends React.Component {
  constructor(props) {
    super(props)

    this.refs = {}

    // build ref object with collapsible elements ids
    this.setRef = (element) => {
      this.refs[element.id] = element
    }

    // toggle "show" CSS class using plain JS
    this.collapseRef = (id) => {
      if (this.refs) this.refs[id].classList.toggle('show')
    }        
  }

  render() {
    return (
      <div>
        <button
          type="button"
          onClick={() => this.collapseRef('content1')}
        >
          Collapse!
        </button>
        <div
          className="collapse"
          // Use the `ref` callback to store a reference to the collapsible DOM element
          ref={this.setRef}
          id="content1"
        >
          Collapsible content
        </div>
      </div>
    )
  }
}

Upvotes: 1

Duong Nhu
Duong Nhu

Reputation: 11

I experienced this before. All you need to do is manually trigger events inside componentDidMount. You might also want to re-triggering the events in the callback of the setState.

Upvotes: 0

Brigand
Brigand

Reputation: 86220

Bootstrap will not work out of the box for react components, since it parses the DOM on load and attaches event listeners etc. You can try something like react-bootstrap or manually triggering inside the componentDidMount lifecycle.

David

Upvotes: 13

Related Questions