Bootstrap collapse with react js

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.


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>
    )
  }
}

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


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