React中记录唯一ID处理及单条批准触发批量提交问题求助
问题:点击单条记录的批准按钮,却触发所有记录复制到目标表且循环执行
我要实现的功能是:前端表格展示待审批用户记录,每条记录对应一个批准按钮,点击后仅将该条记录从pending_users表复制到users表。但现在点击任意一个批准按钮,所有记录都会被复制,还会持续循环执行。
前端代码
import React, { useState, useEffect } from "react"; import axios from "axios"; import '../css/Approve_user.css'; function Approve_user() { const [pendinguser, setPendinguser] = useState([]) useEffect(()=> { axios.get('http://localhost:5500/getpendingdata') .then(res=>setPendinguser(res.data)) .catch(err=>console.log(err)) }, []) const handleApprove = (i) => { axios.post('http://localhost:5500/approveduser', i) .then(res => { if(res.data.Status === 'Success'){ alert("User Approved Successfully!"); window.location.reload() } else{ alert(res.data.Error); } }) .catch(err => console.log(err)); } return( <section className="Approve_users"> <div className="Approve_title"> <h3>Approve New Users Section</h3> <h5>Select and Decline Users</h5> </div> <div className="pendingusers"> <table> <thead> <tr> <th>Ticket ID</th> <th>First Name</th> <th>Last Name</th> <th>Username</th> <th>Gender</th> <th>Location</th> <th>Phone No.</th> <th>Email</th> <th>Category</th> <th>Skill</th> <th>Action</th> </tr> </thead> <tbody> { pendinguser.map((data, i) => ( <tr key={i}> <td>{data.pending_user_ID}</td> <td>{data.pending_user_firstname}</td> <td>{data.pending_user_lastname}</td> <td>{data.pending_user_username}</td> <td>{data.pending_user_gender}</td> <td>{data.pending_user_location}</td> <td>{data.pending_user_phone_no}</td> <td>{data.pending_user_email}</td> <td>{data.pending_user_category}</td> <td>{data.pending_user_skill}</td> <td className="buttons"> <button className='Approve' onClick={handleApprove(i)}>Approve</button> <button className='Delete'>Delete</button> </td> </tr> )) } </tbody> </table> </div> </section> ) } export default Approve_user;
后端代码
app.post('/approveduser', (req, res) => { const sql = "INSERT INTO users(`user_firstname`, `user_lastname`, `user_username`, `user_gender`, `user_location`, `user_phone_no`, `user_email`, `user_password`, `user_category`, `user_profilepic`, `user_skill`) SELECT `pending_user_firstname`, `pending_user_lastname`, `pending_user_username`, `pending_user_gender`, `pending_user_location`, `pending_user_phone_no`, `pending_user_email`, `pending_user_password`, `pending_user_category`, `pending_user_profilepic`, `pending_user_skill` FROM pending_users WHERE pending_user_ID=?"; const approve_ID = req.body.i; db.query(sql, [approve_ID], (err, result) => { if(err) return res.json({Error: err}); else return res.json({Status: "Success"}); }) })
核心问题分析
- 前端事件绑定错误:循环渲染时,
onClick={handleApprove(i)}是直接执行函数而非绑定事件,导致组件加载时就触发所有记录的复制操作。页面刷新后重新渲染,又会重复执行,形成循环。 - 参数传递不合理:传递数组索引
i作为标识,不如直接用记录的唯一ID可靠,索引会随数据变化而改变。
修复方案
前端修改
- 用箭头函数包裹点击事件,确保点击时才调用
handleApprove,并传递记录的pending_user_ID - 优化页面更新逻辑,不用刷新页面,直接通过
setState过滤已批准的记录 - 用记录唯一ID作为
key,避免渲染异常
修改后的关键代码:
// 更新handleApprove函数 const handleApprove = (userId) => { axios.post('http://localhost:5500/approveduser', { userId }) .then(res => { if(res.data.Status === 'Success'){ alert("User Approved Successfully!"); // 移除已批准的用户,避免页面刷新 setPendinguser(prevList => prevList.filter(user => user.pending_user_ID !== userId)); } else{ alert(res.data.Error); } }) .catch(err => console.log(err)); } // 更新按钮和tr的key <tr key={data.pending_user_ID}> {/* ...其他td内容... */} <td className="buttons"> <button className='Approve' onClick={() => handleApprove(data.pending_user_ID)}>Approve</button> <button className='Delete'>Delete</button> </td> </tr>
后端修改
- 接收前端传递的
userId参数,替换原来的req.body.i
修改后的后端代码:
app.post('/approveduser', (req, res) => { const sql = "INSERT INTO users(`user_firstname`, `user_lastname`, `user_username`, `user_gender`, `user_location`, `user_phone_no`, `user_email`, `user_password`, `user_category`, `user_profilepic`, `user_skill`) SELECT `pending_user_firstname`, `pending_user_lastname`, `pending_user_username`, `pending_user_gender`, `pending_user_location`, `pending_user_phone_no`, `pending_user_email`, `pending_user_password`, `pending_user_category`, `pending_user_profilepic`, `pending_user_skill` FROM pending_users WHERE pending_user_ID=?"; const approve_ID = req.body.userId; // 改为接收userId db.query(sql, [approve_ID], (err, result) => { if(err) return res.json({Error: err}); else return res.json({Status: "Success"}); }) })
内容的提问来源于stack exchange,提问作者Joseph Lwambi
相关产品推荐
相关产品推荐

