Logic to keep only one section open at a time

Viewed 51

I'm struggling to come up with the implementation.

It's like a collapsible. I have a card component that has a local useState. Only one radio button should be active, but right now all of them can be active.

I know that using a local state, each card is going to have his own state, so they all can be active at the same time.

In this case, I'll need some kind of unified state or something like that, to handle the selection. But how can I do that?

This is my card component:

import * as S from './styled'
import Radio from '@material-ui/core/Radio'

export default function PackageCard({ packageInformations }) {
  const [selectedValue, setSelectedValue] = React.useState(false)

  const handleChange = () => {
    setSelectedValue(!selectedValue)
  }

  return (
    <>
      <S.FormSectionContainer>
        <S.PackageContainer>
          <S.PackageSelectionContainer>
            <S.PackageNameAndPrice>
              <S.PackageName>{packageInformations.packageName}</S.PackageName>
              <S.PackagePrice>{packageInformations.packagePrice}</S.PackagePrice>
            </S.PackageNameAndPrice>
            <Radio checked={selectedValue} onChange={handleChange} value={selectedValue} name="package" />
          </S.PackageSelectionContainer>

          {selectedValue && (
            <S.PackageInformationContainer>
              <S.PackageDescription>{packageInformations.description}</S.PackageDescription>
            </S.PackageInformationContainer>
          )}
        </S.PackageContainer>
      </S.FormSectionContainer>
    </>
  )
}

In my page, I just:

 {packages.map(packageInfo => (
   <PackageCard packageInformations={packageInfo}/>
 ))}

And this is what I have:

enter image description here

1 Answers

What about putting the state on the level upper?

const PackageCardsList = () => {
  const [checkedIndex, setCheckedIndex] = useState();

  return (
    <>
      {packages.map((packageInfo, index) => (
        <PackageCard
          checked={checkedIndex === index}
          packageInformations={packageInfo}
          onCheck={() => setCheckedIndex(index)}
        />
      ))}
    <>
  );
};

Then handle these two new props in the component PackageCard.

And it will be better if your cards have an ID so you will be able to store the ones instead of indexes. And don't forget about key props for rendering arrays components.

Related