Two instances of the same element seem to share state

Viewed 66

In my React application I have a Collapsible component that I use more than once, like so:

const [openFAQ, setOpenFAQ] = React.useState("");

const handleFAQClick = (question: string) => {
  if (question === openFAQ) {
    setOpenFAQ("");
  } else {
    setOpenFAQ(question);
  }
};

return ({
  FAQS.map(({ question, answer }, index) => (
    <Collapsible
      key={index}
      title={question}
      open={openFAQ === question}
      onClick={() => handleFAQClick(question)}
    >
      {answer}
    </Collapsible>
  ))
})

And the Collapsible element accepts open as a prop and does not have own state:

export const Collapsible = ({
  title,
  open,
  children,
  onClick,
  ...props
}: Props) => {
  return (
    <Container {...props}>
      <Toggle open={open} />
      <Title onClick={onClick}>{title}</Title>
      <Content>
        <InnerContent>{children}</InnerContent>
      </Content>
    </Container>
  );
};

However, when I click on the second Collapsible, the first one opens... I can't figure out why.

A working example is available in a sandbox here.

3 Answers

You will need to ensure that the label and id for each checkbox is the same. Here's a working example

But if you're trying to implement an accordion style, you may need another approach.

on Collapsible.tsx line 36, the input id is set the same for both the Collapsibles. you need to make them different from each other and the problem would be solved.

One thing is that you have the same id which is wrong BUT it can still work. Just change the checkbox input from 'defaultChecked={...}' to 'checked={...}'. The reason is that, if you use defaultSomething - it tells react that even if this value will be changed - do not change this value in the DOM - https://reactjs.org/docs/uncontrolled-components.html#default-values

Changing the value of defaultValue attribute after a component has mounted will not cause any update of the value in the DOM

Related