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
相关产品推荐
相关产品推荐

