Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

284
Visualizações
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 Respostas
Responde à pergunta

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 Relatório

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 Relatório

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda