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

React映射渲染表格时点击按钮始终打印首个元素问题求助

问题排查:点击任意删除按钮始终打印首个列表元素

问题描述

通过map渲染favs列表为表格,每行的删除按钮点击后,无论点击哪一行,控制台始终打印列表首个元素的name。相关代码如下:

favs 状态定义

const [favs, setFavs] = useState([
  { name:"node" },
  { name:"react-js" },
  { name:"node js" }
])

HasFavs.js 文件

import React, { useState } from "react";
import DeleteConfirm from "./DeleteConfirm";
import { Link } from "react-router-dom";

const HasFavs = ({favs,handleDelete}) => {
  const handDel =(e)=>{
    console.log(e)
    handleDelete(e)
  }

  return (
    <span>
      <h1>Welcome to Favorite NPM Packages</h1>
      <Link to="/">Add Fav </Link>
      <div>
        <table>
          <tr>
            <th>Package Name</th>
            <th>Actions</th>
          </tr>
          {
            favs.map((favorite)=>{
              return (
                <tr key={favorite.name}>
                  <td>{favorite.name}</td>
                  <td>
                    <button onClick={()=>console.log(favorite.name)}>press</button> 
                    <DeleteConfirm value={`${favorite.name}`} handleDelete={handDel} />
                  </td>
                </tr>
              )
            })
          }
        </table>
      </div>
    </span>
  );
};

export default HasFavs;

DeleteConfirm.js 文件

import React, { useState } from 'react'

const DeleteConfirm = ({value,handleDelete}) => {
  const del= (e)=>{
    console.log(value)
    console.log(e.target)
    handleDelete()
  }

  return (
    <div>
<button type="button" data-toggle="modal" data-target="#exampleModalCenter">
<i class='fa fa-trash' style={{color:'#555553'}}></i>
</button>

<div className="modal fade" id="exampleModalCenter" tabIndex="-1" role="dialog" aria-labelledby="exampleModalCenterTitle" aria-hidden="true">
  <div className="modal-dialog modal-dialog-centered" role="document">
    <div className="modal-content">
      <div className="modal-body">
        Are you sure You want to delete?
      </div>
      <div className="modal-footer">
        <button type="button" className="btn btn-secondary" data-dismiss="modal">Cancel</button>
        <button type="button" className="btn btn-primary" value={value} onClick={del}>Yes</button>
      </div>
    </div>
  </div>
</div>
      
    </div>
  )
}

export default DeleteConfirm

问题原因

核心问题是Bootstrap模态框的ID重复:

  • 循环渲染DeleteConfirm组件时,每个模态框都使用了相同的id="exampleModalCenter",同时触发按钮的data-target="#exampleModalCenter"也指向同一个ID。
  • HTML中ID必须唯一,当点击任意删除按钮时,浏览器只会找到第一个匹配该ID的模态框,因此始终使用第一个组件实例的value值。

解决方案

为每个DeleteConfirm组件生成唯一的模态框ID,确保每个按钮对应正确的模态框:

修改 DeleteConfirm.js

将模态框的ID和按钮的data-target与传入的value绑定,生成唯一标识:

import React from 'react'

const DeleteConfirm = ({value, handleDelete}) => {
  // 生成唯一的模态框ID
  const modalId = `exampleModalCenter-${value}`;

  const del = () => {
    console.log(value);
    handleDelete(value); // 直接传递要删除的name,替代依赖事件对象
  };

  return (
    <div>
      <button 
        type="button" 
        data-toggle="modal" 
        data-target={`#${modalId}`}
      >
        <i className='fa fa-trash' style={{color:'#555553'}}></i>
      </button>

      <div 
        className="modal fade" 
        id={modalId} 
        tabIndex="-1" 
        role="dialog" 
        aria-labelledby={`${modalId}-Title`} 
        aria-hidden="true"
      >
        <div className="modal-dialog modal-dialog-centered" role="document">
          <div className="modal-content">
            <div className="modal-body">
              Are you sure You want to delete {value}?
            </div>
            <div className="modal-footer">
              <button type="button" className="btn btn-secondary" data-dismiss="modal">Cancel</button>
              <button type="button" className="btn btn-primary" onClick={del}>Yes</button>
            </div>
          </div>
        </div>
      </div>
    </div>
  )
}

export default DeleteConfirm

同步修改 HasFavs.js 中的 handDel 函数

确保handleDelete能正确接收要删除的目标值:

const handDel =(value)=>{
  console.log(value);
  handleDelete(value); // 传递要删除的name给父组件的handleDelete
}

额外优化点

  1. 避免依赖事件对象传递数据,直接传递明确的value更可靠。
  2. 模态框的aria-labelledby使用唯一ID,提升页面可访问性。
  3. 统一React中的类名写法:将<i>标签的class改为className。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 01:31:07