Reactjs:使用状态钩子单击时如何选择一张或多张卡片?

时间:2021-07-13 02:51:21

标签: javascript reactjs typescript react-hooks state

我有一个卡片组件 TemplateList 用于映射我的模板卡片(我通过数组添加它们)。

我想添加一个 onClick 状态挂钩功能,帮助我在点击时选择一张或多张卡片,我该怎么做?

这是我的 TemplateList 组件:

import TemplateCard from 
import styles from "./styles/actionpage.m.css";

export type Template = {
    title: string;
    description: string;
    imgURL: string;
};

type Props = {
    templates: Template[];
};

const TemplateList = ({ templates }: Props) => {
    return (
        <div className={styles.scrollContainer}>
            {templates.map((item) => (
                <TemplateCard
                    title={item.title}
                    description={item.description}
                    img={item.imgURL}
                    classNameToAdd={styles.cardContainer}
                />
            ))}
        </div>
    );
};

export default TemplateList;

这是我的 TemplateCard 组件:

import React from "react";
import styles from "./styles/cards.m.css";

type Props = {
    title: string;
    description: string;
    img: string;
    classNameToAdd?: string;
    selected?: boolean;
    classNameOnSelected?: string;
};

const TemplateCard = ({
    title,
    description,
    img,
    classNameToAdd,
    classNameOnSelected,
    selected,
}: Props) => {
    const { aspectRatio, vmin } = useWindowResponsiveValues();
    let className = `${styles.card} ${classNameToAdd}`;

    if (selected) {
        className += `${styles.card} ${classNameToAdd} ${classNameOnSelected}`;
    }

    return (
        <div style={card} className={className}>
            <img style={imageSize} src={img}></img>
            <div style={cardTitle}>{title}</div>
            <div style={descriptionCard}>{description}</div>
        </div>
    );
};

TemplateCard.defaultProps = {
    classNameOnSelected: styles.selected,
};

export default TemplateCard;

目前,我添加了一个“selected”道具,当为真时给我的卡片一个边框,但这当然会在现在为真时选择所有卡片。

这是我的卡片被选中时的样子。

enter image description here

2 个答案:

答案 0 :(得分:1)

要解决这个问题,您必须为每张卡片赋予自己的状态; <OrchestrationStep Order="10" Type="ClaimsExchange"> <Preconditions> <Precondition Type="ClaimsExist" ExecuteActionsIf="false"> <Value>newUser</Value> <Action>SkipThisOrchestrationStep</Action> </Precondition> <Precondition Type="ClaimsExist" ExecuteActionsIf="false"> <Value>extension_mustResetPassword</Value> <Action>SkipThisOrchestrationStep</Action> </Precondition> <Precondition Type="ClaimEquals" ExecuteActionsIf="false"> <Value>extension_mustResetPassword</Value> <Value>true</Value> <Action>SkipThisOrchestrationStep</Action> <Precondition Type="ClaimsExist" ExecuteActionsIf="true"> <Value>isActiveMFASession</Value> <Action>SkipThisOrchestrationStep</Action> </Precondition> </Preconditions>。 这样每张卡片都会有自己的小逻辑,通过这些逻辑他们可以知道自己是否被选中。

selected

答案 1 :(得分:1)

在 TemplateCard 组件上添加一个 onClick 处理程序并在主 div 上触发它。此外,您需要为您的个人卡提供一些标识,以便我们可以使用它来自的数组的索引。

像这样:

const TemplateCard = ({
    title,
    description,
    img,
    classNameToAdd,
    classNameOnSelected,
    selected,
    handleClick
    index
}: Props) => {
    const { aspectRatio, vmin } = useWindowResponsiveValues();
    let className = `${styles.card} ${classNameToAdd}`;

    if (selected) {
        className += `${styles.card} ${classNameToAdd} ${classNameOnSelected}`;
    }

    return (
        <div style={card} className={className} onClick={()=>handleClick(index)}>
            <img style={imageSize} src={img}></img>
            <div style={cardTitle}>{title}</div>
            <div style={descriptionCard}>{description}</div>
        </div>
    );
};

在您的 TemplateList 组件中,您需要设置一个索引数组(使用 useState)来存储单击的 TemplateCard 的索引,以便您可以检查哪些卡被选中,哪些未被选中。并使用我们传递给子组件的函数设置状态,即 handleClick

像这样:

const [selectedArray,setSelectedArray]=useState([])

const handleClick=(i)=>{
const tempArray =[...selectedArray]
if(tempArray[i]==i){tempArray[i]=undefined}
else {tempArray[i]=i}

setSelectedArray(tempArray)
}

组件将是这样的:

const TemplateList = ({ templates }: Props) => {
    return (
        <div className={styles.scrollContainer}>
            {templates.map((item,index) => (
                <TemplateCard
                    title={item.title}
                    description={item.description}
                    img={item.imgURL}
                    classNameToAdd={styles.cardContainer}
                    index={index}
                    selected={selectedArray[index]==index? true:false}
                    handleClick={handleClick}
                />
            ))}
        </div>
    );
};

现在这里发生的事情是我们使用索引作为标识符,并基于此设置选定卡片的数组。在此基础上,我们将“selected”道具发送到 Card 组件。在那里,您可以根据该道具应用您的样式。

希望您的问题得到解答!!