Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

283
Vistas
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 Respuestas
Responde la pregunta

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 Denunciar

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 Denunciar

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda