Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

282
Views
How to Collapsibles in reactjs?

In the Section 1 div, if it is active the content will be displayed, otherwise not. The problem in the Section 2 div, when I click on it it shows active but it doesn't display the content.

File App.js

const App = () => {
  return (
    <div>
      <Accordition title={`Section 1`}>
        <p>
          Lorem ipsum 1 dolor sit amet, consectetur adipisicing elit, sed do
          eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
          minim veniam, quis nostrud exercitation ullamco laboris nisi ut
          aliquip ex ea commodo consequat.
        </p>
      </Accordition>
      <Accordition title={`Section 2`}>
        <p>
          Lorem ipsum 2 dolor sit amet, consectetur adipisicing elit, sed do
          eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
          minim veniam, quis nostrud exercitation ullamco laboris nisi ut
          aliquip ex ea commodo consequat.
        </p>
      </Accordition>
    </div>
  );
};
export default App;

File components/Accordition.js

const Accordition = ({ title, children }) => {
  const [isActive, setisActive] = useState(false);

  const toggleCollapseContent = () => {
    setisActive(!isActive);
  };

  useEffect(() => {
    let panelContent = document.querySelector(".content");
    window.addEventListener("resize", function () {
      if (isActive) {
        panelContent.style.maxHeight = panelContent.scrollHeight + "px";
      } else {
        panelContent.style.maxHeight = null;
      }
    });
  }, [isActive]);
  useEffect(() => {
    let panelContent = document.querySelector(".content");
    return () =>
      window.removeEventListener("resize", function () {
        if (isActive) {
          panelContent.style.maxHeight = panelContent.scrollHeight + "px";
        } else {
          panelContent.style.maxHeight = null;
        }
      });
  });

  useEffect(() => {
    let panelContent = document.querySelector(".content");
    if (isActive) {
      panelContent.style.maxHeight = panelContent.scrollHeight + "px";
    } else {
      panelContent.style.maxHeight = null;
    }
  });
  return (
    <div className="lp-collapsible-content">
      <div
        className={`title ${isActive ? "active" : ""}`}
        onClick={toggleCollapseContent}
      >
        {title}
      </div>
      <div className="content">{children}</div>
    </div>
  );
};
export default Accordition;

Or see: https://codesandbox.io/s/demoaccordion-otkoo

Thank you everyone

about 4 years ago · Juan Pablo Isaza
3 answers
Answer question

0

You need to specify an id on every Accordion item. Otherwise when you retrieve the content section like this: document.querySelector(".content") it will just retrieve the first div with content class and that's always Section 1.

Set a unique id on every section, pass it as a prop to Accordion component and set it on <div className="lp-collapsible-content" id={id}>. Than you will be able to fetch the content of a specific section like this:

document.querySelector(`#${id} .content`)

Here's a refactored version of your example

about 4 years ago · Juan Pablo Isaza Report

0

First, check your two useEffect without dependency list, this cause performance issue.

Second, you can just render the content conditionaly to avoid to manipulate style.maxHeight, etc.

{isActive  && <div className="content">{children}</div>}

your animation will work fine if there is.

document.querySelector(".content");

the querySelector is global and return the first node found with class '.content' in your case, and may be that is why the second is not shown when active.

about 4 years ago · Juan Pablo Isaza Report

0

You have to provide an id for each <Accordition> component:

<Accordition title={`Section 1`} id='section-1'>

And in Accordition.js use getElementById:

import React, { useEffect, useState } from "react";

const Accordition = ({ title, children, id }) => {
  const [isActive, setisActive] = useState(false);

  const toggleCollapseContent = () => {
    setisActive(!isActive);
    
  };

  useEffect(() => {
    let panelContent = document.getElementById(id);
    window.addEventListener("resize", function () {
      if (isActive) {
        panelContent.style.maxHeight = panelContent.scrollHeight + "px";
      } else {
        panelContent.style.maxHeight = null;
      }
    });
  }, [isActive,id]);
  useEffect(() => {
    let panelContent = document.getElementById(id);
    return () =>
      window.removeEventListener("resize", function () {
        if (isActive) {
          panelContent.style.maxHeight = panelContent.scrollHeight + "px";
        } else {
          panelContent.style.maxHeight = null;
        }
      });
  });

  useEffect(() => {
    let panelContent = document.getElementById(id);
    if (isActive) {
      panelContent.style.maxHeight = panelContent.scrollHeight + "px";
    } else {
      panelContent.style.maxHeight = null;
    }
  });
  return (
    <div className="lp-collapsible-content">
      <div
        className={`title ${isActive ? "active" : ""}`}
        onClick={toggleCollapseContent}
      >
        {title}
      </div>
      <div className="content" id={id}>{children}</div>
    </div>
  );
};
export default Accordition;

Enjoy

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!