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

React中为不同卡片传索引/值:点击仅显示最后一项详情

问题分析与解决

问题原因

你的代码在productsInfo.map循环里为每个商品卡片都渲染了一个<Modal>组件,所有Modal的isOpen都绑定同一个this.state.modalIsOpen状态。点击任意"QUICK VIEW"按钮时,所有Modal会同时激活,由于层级重叠,最后一个Modal会覆盖前面的,导致看起来总是显示最后一项信息。另外你定义了changeProduct方法但未在点击时调用,也没把选中商品传递给模态框。

修复步骤

  • 只保留一个Modal实例:将Modal从循环中移出,放在商品列表容器外,避免重复渲染导致的层级冲突。
  • 存储选中商品到state:点击按钮时把当前商品存入state,模态框基于该状态渲染对应内容。
  • 同步点击事件逻辑:点击"QUICK VIEW"时,先调用changeProduct保存商品,再调用OpenModal打开模态框。
  • 传递商品数据给子组件:将state中的选中商品作为props传给ProductDetailsPopUp,让它展示对应详情。

修复后的完整代码

import React, { Component } from "react";
import { productsInfo } from "./ProductsData";  // 包含数据的JS文件
import Modal from "react-modal";
import "./Products.css";
import ProductDetailsPopUp from "./ProductDetailsPopUp";
import axios from "axios";

Modal.setAppElement("#root");
export default class Products extends Component {
  state = {
    productsData: [],
    modalIsOpen: false,
    showProduct: null, // 新增:存储选中的商品
  };
  
  OpenModal = () => {
    this.setState({ modalIsOpen: true });
  };
  CloseModal = () => {
    this.setState({ modalIsOpen: false });
  };
  changeProduct = (item) => {
    this.setState({ showProduct: item });
  };
  render() {
    return (
      <div className="ProductsContainer">
        {productsInfo.map((item, index) => {
          return (
            <div className="cardHolder" key={item.id}>
              <img src={item.img} alt="Products" />
              <button
                onClick={() => {
                  this.changeProduct(item); // 先保存选中商品
                  this.OpenModal(); // 再打开模态框
                  console.log(index);
                }}
                className="MainProductBtn"
              >
                QUICK VIEW
              </button>
              <p>{item.title}</p>
              <small>{`${item.price} USD`}</small>
            </div>
          );
        })}
        {/* 单个Modal组件,放在循环外部 */}
        <Modal
          className="mainModal"
          style={{
            overlay: {
              backgroundColor: "#3333",
              opacity: 0.4,
              transition: "0.4s",
            },
          }}
          isOpen={this.state.modalIsOpen}
          onRequestClose={this.CloseModal}
        >
          {this.state.showProduct && ( // 确保有选中商品才渲染内容
            <>
              <div className="popupHeader">
                <h3>{this.state.showProduct.title}</h3>
                <button onClick={this.CloseModal}>×</button>
              </div>
              <ProductDetailsPopUp product={this.state.showProduct} /> {/* 传递商品数据给子组件 */}
            </>
          )}
        </Modal>
      </div>
    );
  }
}

额外说明

  • 需确保ProductDetailsPopUp组件能接收product props并展示对应信息,比如在子组件中使用this.props.product.title、this.props.product.price等。
  • 增加this.state.showProduct &&的判断,避免模态框打开时因showProduct为null引发报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 05:55:24