From an API request, I get an array of data like below (I get 100 elements, but here I'm showing only 2):
data: Array(2)
0: {cardId: 270, name: "Basic card" , type: "type1"}
1: {cardId: 345, name: "Special card" , type: "type2"}
I show them in my app, using map()
method.
Each array element is shown in the app through <IonCard>
. The card name is in <IonCardTitle>
and the card type is in <IonCardContent>
.
For the moment, with my actual implementation, when I click on a specific <IonCardTitle>
, the contents of all elements are opened.
My goal is: When clicking on a specific element title, open ONLY the content of that element. How can I achieve this?
Any help would be really appreciated.
Cards page:
import {
IonContent,
IonPage,
IonCard,
IonCardHeader,
IonCardTitle,
IonCardContent,
IonItem,
IonLabel,
IonIcon,
} from "@ionic/react";
import React, { useEffect, useRef, useState } from "react";
import { Http} from "@capacitor-community/http";
const Cards: React.FC = () => {
const [cards, setCards] = useState([]);
const [content, setContent] = useState([]);
const [showContent, setShowContent] = useState([]);
const mounted = useRef(true);
useEffect(() => {
mounted.current = true;
const options = {
url: "xxx/cards",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
};
Http.request({ ...options, method: "GET" }).then(
(response) => {
if (mounted.current) {
setCards(response.data);
}
},
(error) => {
const _content =
(error.response && error.response.data) ||
error.message ||
error.toString();
setContent(_content);
}
);
return () => {
mounted.current = false;
};
}, []);
return (
<React.Fragment>
<IonPage className="ion-page" id="main-content">
<IonContent className="ion-padding">
{cards &&
cards.map((card: any) => (
<IonCard key={card.cardId}>
<IonCardHeader>
<IonCardTitle>
<IonItem
button
onClick={() => {
setShowContent(true);
if (showContent === true) {
setShowContent(false);
}
}}
>
<IonIcon
slot="end"
icon={showDetails ? arrowDown : arrowForward}
></IonIcon>
<IonLabel>
<b>{card.name}</b>
</IonLabel>
</IonItem>
</IonCardTitle>
</IonCardHeader>
{showContent && (
<IonCardContent>
<p>Card Type: {card.type}</p>
</div>
</IonCardContent>
)}
</IonCard>
))}
</IonContent>
</IonPage>
</React.Fragment>
);
};
export default Cards;
First, update initial state:
const [showContent, setShowContent] = useState(null);
Then, update onClick:
onClick={() => {
setShowContent(card.cardId);
if (showContent === card.cardId) {
setShowContent(null);
}
}}
Final, update condition render content:
{showContent === card.cardId && (<IonCardContent>...</IonCardContent>)