I am sending data as an array of object from main component file to Accordion component -
return <Accordion items={items} />; items consist of 3 properties - Id, title and data.
Accordion component receives all data and then displays in the browser-
function Accordion({ items }) {
const [expandedId, setExpandedId] = useState("");
const handleClick = (id) => {
if (expandedId === id) {
setExpandedId("");
} else {
setExpandedId(id);
}
//console.log(id);
};
const renderedItem = items.map((item) => {
const isExpanded = expandedId === item.id;
const content = isExpanded && <div>{item.data}</div>;
const icon = <span>{isExpanded ? 'iconOpen' : 'iconClosed'}</span>;
return (
<div key={item.id}>
<div onClick={() => handleClick(item.id)}>
{item.title}
{icon}
</div>
{content}
</div>
);
});
return <div>{renderedItem}</div>;
}
export default Accordion;
Issue with this solution is this I am able to implement Accordion but only one accordion is opening at a time. If I click on other Accordion, the one that was opened gets closed.
I am aware that this can be implemented if I send a single data from main component to Accordion component like this -
Main.js
<div>
{items.map(({ id, title, data }) => (
<Accordion key={id} title={title} data={data} />
))}
</div>
Accordion.js
function Accordion({ id, title, data }) {
const [active, setActive] = useState(false);
const icon = <span>{isExpanded ? 'iconOpen' : 'iconClosed'}</span>;
return (
<div key={id}>
<div onClick={() => setActive(!active)}>
{title}
{icon}
</div>
{active && <div>{data}</div>}
</div>
);
}
export default Accordion;
But I want to handle all logic in Accordion component and not depending upon main component to send data via prop one by one