I’m currently building a custom accordion in React using <details />
and <summary />
Here’s what I have so far – codesandbox
As you can see in the codesandbox, a weird problem is happening. Every time I click on one of the accordions, only the last item’s content shows up. I can’t figure out what’s causing the weird issue.
A snippet of my handle click function, for a full code please refer to the sandbox link above:
const handleClick = (e) => { e.preventDefault(); const accordion = summaryRef.current.parentNode; const content = contentRef.current; if (accordion.hasAttribute("open")) { content.style.removeProperty("max-height"); content.classList.add("closed"); setTimeout(() => { accordion.removeAttribute("open"); }, 400); return; } // If the <details> element is closed, add the [open] attribute (so the content will render), and animate in accordion.setAttribute("open", ""); // Get proper max-height for element for better animation if (!content.getAttribute("data-height")) { content.style.maxHeight = "none"; content.setAttribute( "data-height", `${content.getBoundingClientRect().height}px` ); content.style.removeProperty("max-height"); } // Wait for the browser to apply [open] to <details>, then animate setTimeout(() => { content.classList.remove("closed"); content.style.maxHeight = content.getAttribute("data-height"); }, 0); };
Any help/suggestions would be greatly appreciated!!
Advertisement
Answer
This is happening because you re-reference summaryRef
and contentRef
in a for
loop. Because that the actual value of refs will be last item. I advice to make items as a separate components and keep refs under them.