typescript Reactjs:如何选择一个或多个卡时,点击状态挂钩?

2ic8powd  于 2022-11-26  发布在  TypeScript
关注(0)|答案(2)|浏览(144)

我有一个卡片组件TemplateList,用于Map我的模板卡片(我通过数组添加它们)。
我想添加一个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;

目前,我添加了一个“选中”的道具,当为真时,它会给我的牌一个边框,但现在这当然会选择所有为真的牌。
这就是我的牌在被选中时的样子。

uplii1fm

uplii1fm1#

要实现这一点,您必须为每张卡指定自己的状态; selected。这样,每张卡都将具有它们自己的微小逻辑,通过该逻辑它们将知道它们是否被选中。

// TemplateCard.js
...

const TemplateCard = ({
    title,
    description,
    img,
    classNameToAdd,
    classNameOnSelected,
    /* selected,  we will make this a state instead of prop */
}: Props) => {
    const { aspectRatio, vmin } = useWindowResponsiveValues();

    const [selected, setSelected] = useState(false); // Added state

    // Added handler
    const handleClick = () => {
      setSelected(!selected);
    };

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

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

lztngnrs2#

在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),该数组存储已单击的TemplateCards的索引,以便您可以检查哪些卡已被选中,哪些卡未被选中。
就像这样:

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组件。在那里,您可以根据该属性应用样式。
希望您的问题得到了解答!!

相关问题