Search code examples
reactjsreact-bootstrap

React-Bootstrap Collapse not working with custom components


I've encountered a situation where Collapse does not seem to work properly when it's used to wrap a class component, though it does seem to work correctly when it wraps a simple JSX element.

You can see this in action in this example: https://codesandbox.io/embed/flamboyant-dhawan-4rf4b?fontsize=14&hidenavigation=1&theme=dark

Note that in both cases where Collapse is used, it is initialized with in={false}, but whereas this works when wrapping a definition list, it does not work when wrapping a custom component that provides a definition list.

Am I misunderstanding how Collapse should be used? Or can anyone suggest a solution to allow Collapse to work as intended when wrapping a class component?

Here's the same code linked above for convenience:

import React from "react";

import Collapse from "react-bootstrap/Collapse";
import Container from "react-bootstrap/Container";

import "./App.css";

class BasicList extends React.Component {
  render() {
    return (
      <dl id={this.props.id} className="row">
        <dt className="col-md-3">Name</dt>
        <dd className="col-md-9">{this.props.name}</dd>

        <dt className="col-md-3">Address</dt>
        <dd className="col-md-9">{this.props.address}</dd>

        <dt className="col-md-3">Favorite Color</dt>
        <dd className="col-md-9">{this.props.color}</dd>
      </dl>
    );
  }
}

const App = () => (
  <Container className="p-3">
    <h1 className="header">Collapse Example</h1>

    <p>
      <em>Ex 1: BasicList component that renders a DL</em>
    </p>
    <BasicList
      id="0"
      name="Wednesday Addams"
      address="0001 Cemetery Lane"
      color="black"
    />

    <p>
      <em>
        Ex 2: BasicList component that renders a DL inside a Collapse. It should
        be collapsed, but it is not.
      </em>
    </p>
    <Collapse in={false}>
      <BasicList
        id="1"
        name="Eddie Munster"
        address="1313 Mockingbird Lane"
        color="grey"
      />
    </Collapse>

    <p>
      <em>Ex 3: A simple DL element inside a Collapse. It is collapsed.</em>
    </p>
    <Collapse in={false}>
      <dl id="2" className="row">
        <dt className="col-md-3">Name</dt>
        <dd className="col-md-9">Theodore Cleaver</dd>

        <dt className="col-md-3">Address</dt>
        <dd className="col-md-9">485 Mapleton Drive</dd>

        <dt className="col-md-3">Favorite Color</dt>
        <dd className="col-md-9">Blue</dd>
      </dl>
    </Collapse>
  </Container>
);

export default App;

Solution

  • When Collapse component is collapsed, it adds .collapse class to the immediate child element. It's not able to add a class as I can see it in your code since BasicList is a component. However, you can wrap BasicList component in a div.

    <Collapse in={false}>
        <div>
            <BasicList
                id="1"
                name="Eddie Munster"
                address="1313 Mockingbird Lane"
                color="grey"
            />
        </div>
    </Collapse>
    

    You can see a working example.