Firas SCMP
Firas SCMP

Reputation: 541

how to use useState react hook for more than one element?

I'm building a full-stack website using mern (mongo express reactjs and nodejs) for the first time in using react hooks. So I have bootstrap cards with a collapse button to hide card body text, but I have 6 cards and the collapse button works with the useState hook, in a way that onClick sets the expand property to false and vise versa. My question is that should I use 6 useState hooks for the 6 cards? or in any way, there's some solution. ps. that if the same hook is used on all cards then onClick will expand all cards.

here's my code of one useState and one card:

const [open1, setOpen1] = useState(false);
 <Button

        onClick={() => setOpen1(!open1)}
        aria-controls="example-collapse-text"
        aria-expanded={open1}
      >
        click
      </Button>
      <Collapse in={open1}>
        <div id="example-collapse-text">
        This is a longer card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.
        </div>
      </Collapse>

Upvotes: 0

Views: 1895

Answers (3)

Sahil Rajpal
Sahil Rajpal

Reputation: 540

What you need to do is , make a folder named component (name not necessarily be same but this is very much followed). In that folder make you card component like this

import React, { useState } from "react";

const card = ({ prop1, prop2 }) => {
  const [isOpen, setOpen] = useState(false);

  const collapseListener = () => {
    setOpen((prvState) => !prvState);
  };

  return (
    <div>
      <button onClick={collapseListener}>{/* button to collapse */}</button>
      <collable collapse={isOpen}>
        {/* your collapasble component */}
        <h1>{prop1}</h1>
        <h1>{prop2}</h1>
      </collable>
    </div>
  );
};

export default card;

Then you can import this card component from anywhere and can use it like this

<Card prop1={'first'} prop2={'second'}  />

Upvotes: 0

Firas SCMP
Firas SCMP

Reputation: 541

well this was solved by making a component for the card and then using it as an jsx element.

export default function DepartmentCard() {
const [open, setOpen] = useState(false);

<Button
onClick={() => setOpen(open)}
aria-controls="example-collapse-text"
aria-expanded={(open === 1)? true : false}>
click
</Button>
<Collapse in={open}>
<div id="example-collapse-text">
This is a longer card with supporting text below as a natural
    lead-in to additional content. This content is a little bit longer.
</div>
</Collapse>
}

btw it's the same code but instead of using it 6 times, I made as one component, and used the component tag 6 times. but the difference is that now each component has it's own state

Example:

ReactDOM.render(
<div>
<DepartmentCard/>
<DepartmentCard/>
<DepartmentCard/>
<DepartmentCard/>
<DepartmentCard/>
<DepartmentCard/>
</div>

or you can simply use the map() function or a loop to render the 6 cards. and you can use props to change the body of each card.

Upvotes: 2

Ajith
Ajith

Reputation: 2666

Can you try the following logic ?

const [open, setOpen] = useState(1);
<Button
onClick={() => setOpen(1)}
aria-controls="example-collapse-text"
aria-expanded={(open === 1)? true : false}>
click
</Button>
<Collapse in={(open === 1)? true : false}>
<div id="example-collapse-text">
This is a longer card with supporting text below as a natural
    lead-in to additional content. This content is a little bit longer.
</div>
</Collapse>

<Button
  onClick={() => setOpen(2)}
  aria-controls="example-collapse-text"
  aria-expanded={(open === 2)? true : false}>
  click
</Button>
<Collapse in={(open === 2)? true : false}>
  <div id="example-collapse-text">
  This is a longer card with supporting text below as a natural
      lead-in to additional content. This content is a little bit longer.
  </div>
</Collapse>

Upvotes: 0

Related Questions