3

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>
    </>
  );
};
Drew Reese
  • 165,259
  • 14
  • 153
  • 181
JPWilson
  • 691
  • 4
  • 14

1 Answers1

1

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>

Edit react-bootstrap-collapse-only-have-one-item-collapsed-at-any-time

Drew Reese
  • 165,259
  • 14
  • 153
  • 181
  • Hi thank you so much really helped me out! Can i ask a follow up question though, i am getting the error Binding element 'open' implicitly has an 'any' type and Binding element 'onclick' implicitly has an 'any' type. The code works as intended but visual code has an annoying red squiggle how do I fix this or suppress it I am using react tsx? – JPWilson Oct 22 '22 at 03:02
  • 1
    @JPWilson I have added a Typescript version to my answer. Please do check it when you have availability. – Drew Reese Oct 22 '22 at 07:38