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.