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

如何在map函数中使用React-Bootstrap Modal?解决内容显示异常

解决模态框点击任意按钮只显示第一条数据的问题

问题根源是你给每个列表项都渲染了一个ModalPhoto组件,且所有模态框共用同一个show状态。点击任意按钮触发setShow(true)时,所有模态框都会被打开并重叠在一起,视觉上只会显示其中一个(你看到的第一条),这完全没必要。

正确的做法是只渲染一个模态框,用状态存储当前要展示的项的数据,点击按钮时把对应项的数据存入状态,再打开模态框。

修改后的父组件代码

import { useState } from 'react';
import ModalPhoto from './modal';

function YourTableComponent() {
  // 新增状态存储当前选中的项
  const [selectedItem, setSelectedItem] = useState(null);
  const [show, setShow] = useState(false);

  const openModal = (item) => {
    // 先存入当前点击的项,再打开模态框
    setSelectedItem(item);
    setShow(true);
  };

  return (
    <>
      <Table>
        <thead>
          <tr>
            <th>miniaturka</th>
            <th>nazwa</th>
            <th>cena</th>
          </tr>
        </thead>
        <tbody>
          {/* 修正map参数命名,避免变量名冲突:item为当前项,index为索引 */}
          {zestawy.map((item, index) => {
            return (
              <tr key={item.id}>
                <th>
                  <Image src={`/nowemodule/${index}.webp`} width={100} height={100} />
                </th>
                <td>
                  {/* 点击时传入当前项数据 */}
                  <Button onClick={() => openModal(item)}>
                    {item.name} {item.wielkości}
                  </Button>
                </td>
                <td>{cena(index).toFixed(2)} zł</td>
              </tr>
            );
          })}
        </tbody>
      </Table>
      {/* 只渲染一个模态框,放在循环外部,使用选中项的数据 */}
      <ModalPhoto
        show={show}
        setShow={setShow}
        title={selectedItem?.name || ''}
        content={selectedItem?.description || ''}
        photo={selectedItem ? `/nowemodule/${zestawy.indexOf(selectedItem)}.webp` : ''}
      />
    </>
  );
}

模态框组件(可小幅优化)

function ModalPhoto({ title, content, photo, show, setShow }) {
  const handleClose = () => setShow(false);

  return (
    <Modal show={show} onHide={handleClose}>
      <Modal.Header closeButton>
        <Modal.Title>{title}</Modal.Title>
      </Modal.Header>
      <Modal.Body>
        <p>{content}</p>
      </Modal.Body>
      {/* 图片存在时再渲染,避免空值报错 */}
      {photo && <Image src={photo} width={100} height={100} />}
      <Modal.Footer>
        <Button variant="secondary" onClick={handleClose}>Close</Button>
      </Modal.Footer>
    </Modal>
  );
}

export default ModalPhoto;

关键改动说明

  • 新增selectedItem状态,专门存储当前点击项的完整数据,彻底避免多个模态框的数据冲突
  • 把ModalPhoto移到列表循环外部,只渲染一个模态框,减少不必要的DOM节点
  • 修改按钮点击事件,通过箭头函数把当前项传入openModal,确保打开的是对应项的内容
  • 用可选链?.和空值判断处理selectedItem为空的情况,避免页面报错
  • 修正map的参数命名,解决原代码中变量名重复导致的混淆问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 04:45:44