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:
JavaScript
x
32
32
1
const handleClick = (e) => {
2
e.preventDefault();
3
4
const accordion = summaryRef.current.parentNode;
5
const content = contentRef.current;
6
7
if (accordion.hasAttribute("open")) {
8
content.style.removeProperty("max-height");
9
content.classList.add("closed");
10
setTimeout(() => {
11
accordion.removeAttribute("open");
12
}, 400);
13
return;
14
}
15
// If the <details> element is closed, add the [open] attribute (so the content will render), and animate in
16
accordion.setAttribute("open", "");
17
// Get proper max-height for element for better animation
18
if (!content.getAttribute("data-height")) {
19
content.style.maxHeight = "none";
20
content.setAttribute(
21
"data-height",
22
`${content.getBoundingClientRect().height}px`
23
);
24
content.style.removeProperty("max-height");
25
}
26
// Wait for the browser to apply [open] to <details>, then animate
27
setTimeout(() => {
28
content.classList.remove("closed");
29
content.style.maxHeight = content.getAttribute("data-height");
30
}, 0);
31
};
32
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.