How do I convert the below code so that if I call
<div><Example/></div>
<div><Example/></div>
<div><Example/></div>
When I click on one Example item and then click on another one the previously opened Example item closes? Currently, the item will only close when it is clicked on and will stay open if I click on another.
function Example() {
const [open, setOpen] = useState(false);
return (
<>
<Button
onClick={() => setOpen(!open)}
aria-controls="example-collapse-text"
aria-expanded={open}
className="Collapse-Test"
data-open={open}
>
click
</Button>
<Collapse in={open}>
<div id="example-collapse-text">
Hidden Text
</div>
</Collapse>
</>
);
};
CodePudding user response:
Lift the state up to the parent component so it can control what is currently selected and toggled open. Update the Example component to take open and onClick props.
Example component
interface IExample {
open: boolean;
onClick: () => void;
}
function Example({ open, onClick }: IExample) {
return (
<>
<Button
onClick={onClick}
aria-controls="example-collapse-text"
aria-expanded={open}
className="Collapse-Test"
data-open={open}
>
click
</Button>
<Collapse in={open}>
<div id="example-collapse-text">
Hidden Text
</div>
</Collapse>
</>
);
};
Parent component
const [openId, setOpenId] = useState<number | null>(null);
const toggleHandler = (id: number) => () => {
// toggle closed if already open, otherwise set new open id
setOpenId(openId => openId === id ? null : id);
};
...
<div>
<Example open={openId === 1} onClick={toggleHandler(1)} />
</div>
<div>
<Example open={openId === 2} onClick={toggleHandler(2)} />
</div>
<div>
<Example open={openId === 3} onClick={toggleHandler(3)} />
</div>
