I have a list of cards. After click on each card I want them to expand with little bit more info. I get the cards from the server and map them. To expand single card, not multiple, I've created a state editIndex which checks the id of the card so it could work correctly and expand specifically that card. I can't figure out, how do I expand one card and other at the same time. Because right now if I click on card, the other one which was expanded is collapsing.
const [studentList, setStudentList] = useState();
const [input, setInput] = useState(" ");
const [editIndex, setEditIndex] = useState(null);
const [suggestions, setSuggestions] = useState(null);
const handleExpand = (id) => {
setEditIndex((e) => (e === id ? null : id))};
return (
<div
className="flex
flex-col
w-4/5
h-[800px]
overflow-scroll
scrollbar-hide
border
bg-white
rounded-xl
"
>
<div>
{studentList?.map(
({
city,
company,
email,
firstName,
grades,
id,
lastName,
pic,
skill,
}) => (
<div
key={uuidv4()}
onClick={(e) => handleExpand(id)}
className="flex border-b-2 py-2 px-7 xl:px-12 cursor-pointer
mb-2 max-h-96 transition transform ease duration-200;
"
>
<div className="flex items-center ">
<img
src={pic}
className="flex items-center border rounded-full object-cover w- [100px] h-[100px]"
/>
</div>
<div className="ml-10 superTest ">
<p className="font-bold text-4xl">
{firstName} {lastName}
</p>
<p>E-mail: {email}</p>
<p>Company: {company}</p>
<p>Skill: {skill}</p>
<p>Average: {grades}% </p>
{editIndex === id && (
<div>
<p>1</p>
<p>2</p>
<p>3</p>
<p>4</p>
<p>5</p>
</div>
)}
</div>
</div>
)
)}
</div>
</div>
);
}
export default Card;
Instead of editIndex
, have a Set
of the id
values of expanded cards:
const [editing, setEditing] = useState(new Set());
Then, to expand/contract a card (sadly, Set
has no built-in toggle
method):
const handleExpand = (id) => {
setEditing(editing => {
// Copy the set
editing = new Set(editing);
if (editing.has(id)) {
// Already editing, stop editing
editing.delete(id);
} else {
// Not editing, start
editing.add(id);
}
return editing;
});
};
To determine whether a card is expanded, it's editing.has(id)
:
{editing.has(id) && (
<div>
<p>1</p>
<p>2</p>
<p>3</p>
<p>4</p>
<p>5</p>
</div>
)}
Try to use an array or map of expanded cards:
const [editIndex, setEditIndex] = useState([]);
...
const handleExpand = (id) => {
setEditIndex((e) => (e.includes(id) ? e.filter(i => i !== id) : [...e, id]))
};
...
{editIndex.includes(id) && (
<div>
<p>1</p>
<p>2</p>
<p>3</p>
<p>4</p>
<p>5</p>
</div>
)}
You should state with an object and keep expanded card ids in the object. Using object instead of an array you avoid loop to filter the array
import React, { useState } from 'react';
function Card() {
const [studentList, setStudentList] = useState();
const [editIndex, setEditIndex] = useState({});
const handleExpand = (id) => {
setEditIndex((e) => (e === id ? null : id))
setEditIndex({id: !editIndex[id]});
};
return studentList.map((student, index) =>
<div onClick={() => handleExpand(index)} className={`otherClassNames ${editIndex[index]?"expanded":"collapsed"}`}>
{JSON.stringify(student)} // render student data
</div>
);
}
export default Card;
On the other hand, you can use the Collapse component of the Ant Design library. So leave the collapse issue them.
https://ant.design/components/collapse/
and other complicated components are available in the library use should check out.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.