You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React点击商品卡片更多信息时所有弹窗同时触发问题求解

问题根源

你当前将控制弹窗显隐的showModal状态定义在所有商品卡片的公共父层级,所有卡片共用同一个布尔类型的状态值,因此只要状态变为true,所有卡片内嵌的Modal组件都会同时触发显示;另外你在点击事件中传入了商品id,但状态更新逻辑完全没有用到这个参数,也无法区分当前触发的是哪张卡片。

修复方案(两种可选)

方案1:父组件存储激活的商品ID(改动最小)

修改状态为存储当前打开弹窗的商品ID,而非全局布尔值,只有当前卡片ID和激活ID匹配时才显示对应弹窗:

import React, {useState} from 'react';
import Modal from '../Modal';
import productCard from "./productData";

function Card() {
    // 改为存储当前激活弹窗的商品id,null表示没有弹窗打开
    const [activeModalId, setActiveModalId] = useState(null);
    // 打开弹窗:传入点击的商品id
    const openModal = (id) => { 
      setActiveModalId(id)
    };
    // 关闭弹窗
    const closeModal = () => {
      setActiveModalId(null)
    }

    const listitems =  productCard.map((item) =>
    <div className="card" key={item.id}>
        <div className="card_img">
            <img src={item.thumb} alt={item.product_name} />
        </div>
        <div className="card_header">
            <h2>{item.product_name}</h2>
            <p>{item.description}</p>
            <button className="description" onClick={() =>openModal(item.id)}>More Info</button>
            {/* 只有当前卡片id等于激活id时才显示弹窗 */}
            <Modal showModal={activeModalId === item.id} setShowModal={closeModal} />
            <p className="price">{item.price}<span>{item.currency}</span></p>
            <div className="btn">Add to cart</div>
        </div>
    </div>)

    return (
        <>   
            <h2 className="content_title">Product list</h2>
            <div className="main_content">
                <h3>MOBILES</h3>             
                {listitems}
            </div>
        </>
    )
}
export default Card;

Modal组件无需修改即可正常使用。

方案2:拆分独立卡片子组件(更解耦,推荐)

把单个商品卡片拆成独立组件,每个组件自己维护弹窗状态,完全避免互相干扰:
首先新建ProductCard.js组件:

import React, {useState} from 'react';
import Modal from '../Modal';

function ProductCard({item}) {
    // 每个卡片自己维护弹窗状态,互不影响
    const [showModal, setShowModal] = useState(false);
    const toggleModal = () => setShowModal(prev => !prev);

    return (
        <div className="card">
            <div className="card_img">
                <img src={item.thumb} alt={item.product_name} />
            </div>
            <div className="card_header">
                <h2>{item.product_name}</h2>
                <p>{item.description}</p>
                <button className="description" onClick={toggleModal}>More Info</button>
                <Modal showModal={showModal} setShowModal={toggleModal} />
                <p className="price">{item.price}<span>{item.currency}</span></p>
                <div className="btn">Add to cart</div>
            </div>
        </div>
    )
}
export default ProductCard;

再修改原来的Card组件:

import React from 'react';
import ProductCard from './ProductCard';
import productCard from "./productData";

function Card() {
    return (
        <>   
            <h2 className="content_title">Product list</h2>
            <div className="main_content">
                <h3>MOBILES</h3>             
                {productCard.map(item => <ProductCard key={item.id} item={item} />)}
            </div>
        </>
    )
}
export default Card;

内容的提问来源于stack exchange,提问作者user17320926

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 08:54:03