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

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"}); 
    })
})

核心问题分析

  1. 前端事件绑定错误:循环渲染时,onClick={handleApprove(i)}是直接执行函数而非绑定事件,导致组件加载时就触发所有记录的复制操作。页面刷新后重新渲染,又会重复执行,形成循环。
  2. 参数传递不合理:传递数组索引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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 18:32:05