<div class="accordion">
  <div class="accordion-panel">
    <h3 class="accordion-header">Panel 1</h3>
    <div class="accordion-body">These are the contents of panel 1</div>
  </div>
  <div class="accordion-panel accordion-expanded">
    <h3 class="accordion-header">Panel 2</h3>
    <div class="accordion-body">These are the contents of panel 2</div>
  </div>
  <div class="accordion-panel">
    <h3 class="accordion-header">Panel 3</h3>
    <div class="accordion-body">These are the contents of panel 3</div>
  </div>
</div>
.accordion-header {
  cursor: pointer;
}

.accordion-panel {
  border: 1px dashed black;
  margin: 2px;
  padding: 5px;
}

.accordion-panel > .accordion-body {
  display: none;
}

.accordion-panel.accordion-expanded > .accordion-body {
  display: block;
}
class Accordion extends React.Component {
  componentDidMount() {
    const { onLoad, element } = this.props;
    
    const panels = element.querySelectorAll(".accordion-panel");
    for (const panel of panels) {
      const head = panel.querySelector(".accordion-header");
      head.addEventListener(
        'click',
        () => this.handleClick(panel)
      )
    }
    
    onLoad(element.querySelector(".accordion-expanded"));
  }
  
  handleClick = (panel) => {
    this.props.onClickPanel(panel);
  }
  
  componentDidUpdate() {
    const { element, active } = this.props;
    const panels = element.querySelectorAll(".accordion-panel");
    for (const panel of panels) {
      panel.classList.toggle("accordion-expanded", panel === active);
    }
  }
  
  render() {
    return null;
  }
}

class Accordions extends React.Component {
  constructor() {
    super();
    
    const active = new Map();
    const accordions = document.querySelectorAll(".accordion");
    for (const accordion of accordions) {
      active.set(accordion, null);
    }
    this.state = {
      active
    };
  }
  
  handleClick = (accordion, panel) => {
    this.setState(state => {
      // clone the map
      const active = new Map(state.active);
      if (active.get(accordion) === panel) {
        active.set(accordion, null);
      } else {
        active.set(accordion, panel);
      }
      return { active };
    });
  };

  onAccordionLoad = (accordion, panel) => {
    this.setState(state => {
      // clone the map
      const active = new Map(state.active);
      active.set(accordion, panel);
      return { active };
    });
  };

  render() {
    return Array.from(
      this.state.active.keys(),
      acc => (
        <Accordion
          active={this.state.active.get(acc)}
          element={acc}
          onLoad={active => this.onAccordionLoad(acc, active)}
          onClickPanel={panel => this.handleClick(acc, panel)}
          />
      )
    )
  }
}

ReactDOM.render(
  <Accordions/>,
  document.createElement('div') // detached container
)
View Compiled
Rerun