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 }
额外优化点
- 避免依赖事件对象传递数据,直接传递明确的
value更可靠。 - 模态框的
aria-labelledby使用唯一ID,提升页面可访问性。 - 统一React中的类名写法:将
<i>标签的class改为className。
内容的提问来源于stack exchange,提问作者Vivek Maddeshiya
相关产品推荐
相关产品推荐

