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

React后台管理系统删除用户后数据表格无法自动刷新求助

问题解决:删除用户后自动刷新数据表格

问题背景

开发基于MongoDB的Admin Dashboard用户模块,包含用户表格展示、新增/删除用户功能。当前核心问题:删除用户后数据库已移除该用户,但前端表格未自动更新,需手动刷新页面或点击刷新按钮。矛盾点:

  • 删除函数getUser定义在Users组件外部,无法直接调用组件内部的fetchUsers刷新表格
  • 将fetchUsers移到组件外,又依赖组件内的setUserRows无法实现
  • 将getUser移到组件内,因该函数已在组件外被使用而不可行

可行解决方案

方案1:让getUser返回Promise,组件内链式触发刷新

修改getUser使其返回Promise,在组件内调用删除操作后,成功时直接调用fetchUsers。同时将表格列定义移入组件内部(或做成参数化函数),让渲染函数能访问组件内的fetchUsers。

步骤1:修改getUser函数

const getUser = async (userId) => {
    try {
        const res = await axios.delete(`/api/auth/deleteUser/${userId}`, {
            headers: {
                "Content-Type": "application/json",
            },
        });
        return res; // 返回响应便于后续处理
    } catch (e) {
        console.log(e);
        throw e; // 抛出错误供调用方捕获
    }
}

步骤2:调整表格列定义

将columns移入组件内部,或做成接受fetchUsers的参数化函数:

// 外部定义可复用的列生成函数
const getColumns = (fetchUsers) => [
    { field: "id", headerName: "ID", width: 250 },
    { field: "username", type: "string", headerName: "Username", width: 120 },
    { field: "email", type: "string", headerName: "Email", width: 200 },
    { field: "phoneNumber", type: "number", headerName: "Phone", width: 120 },
    { field: "createdAt", headerName: "Created At", width: 100, type: "string" },
    { field: "verified", headerName: "Verified", width: 70, type: "boolean" },
    {
        field: "action",
        headerName: "Actions",
        width: 100,
        renderCell: (params) => {
            return (
                <div className="action">
                    <Link to="">
                        <img src="/Dashboard/view.svg" alt="" />
                    </Link>
                    <div className="delete" onClick={() => {
                        getUser(params.row.id)
                            .then(() => fetchUsers()) // 删除成功后刷新表格
                            .catch(err => console.error("删除用户失败:", err))
                    }}>
                        <img src="/Dashboard/delete.svg" alt="" />
                    </div>
                </div>
            );
        },
    }
]

步骤3:组件内调用列生成函数

const Users = () => {
    // ...其他状态和函数
    
    const columns = getColumns(fetchUsers);
    
    // ...组件剩余代码
}

方案2:让getUser接受成功回调函数

给getUser增加可选回调参数,删除成功后执行传入的刷新函数。

步骤1:修改getUser函数

const getUser = async (userId, onSuccess) => {
    try {
        await axios.delete(`/api/auth/deleteUser/${userId}`, {
            headers: {
                "Content-Type": "application/json",
            },
        });
        if (typeof onSuccess === 'function') {
            onSuccess(); // 删除成功后执行刷新回调
        }
    } catch (e) {
        console.log(e);
    }
}

步骤2:组件内调用时传入fetchUsers

同样需要将columns移入组件或做成参数化函数,在删除按钮点击事件中传入回调:

<div className="delete" onClick={() => getUser(params.row.id, fetchUsers)}>
    <img src="/Dashboard/delete.svg" alt="" />
</div>

方案3:本地状态直接更新(减少API请求)

如果不想重新请求全量用户数据,可在删除成功后直接从本地状态中移除被删除的用户:

const handleDelete = async (userId) => {
    try {
        await getUser(userId);
        // 直接更新本地状态,移除目标用户
        setUserRows(prev => prev.filter(row => row.id !== userId));
    } catch (err) {
        console.error("删除失败:", err);
        // 失败时重新拉取数据保证一致性
        fetchUsers();
    }
}

在删除按钮点击事件中调用handleDelete即可。

完整代码示例(方案1)

import DataTable from "../dataTable/DataTable"
import "./userspagedb.scss"
import {useEffect, useState} from "react"
import Add from "../addUser/Add"

import axios from "axios";
import AddUserBtn from "../../../Buttons/addUserBtn/addUser";
import AddUserForm from "../../../Buttons/addUserForm/addUserForm";

import { userRows } from "../../data"
import {Link} from "react-router-dom";

const getUser = async (userId) => {
    try {
        const res = await axios.delete(`/api/auth/deleteUser/${userId}`, {
            headers: {
                "Content-Type": "application/json",
            },
        });
        return res;
    } catch (e) {
        console.log(e);
        throw e;
    }
}

const getColumns = (fetchUsers) => [
    { field: "id", headerName: "ID", width: 250 },
    { field: "username", type: "string", headerName: "Username", width: 120 },
    { field: "email", type: "string", headerName: "Email", width: 200 },
    { field: "phoneNumber", type: "number", headerName: "Phone", width: 120 },
    { field: "createdAt", headerName: "Created At", width: 100, type: "string" },
    { field: "verified", headerName: "Verified", width: 70, type: "boolean" },
    {
        field: "action",
        headerName: "Actions",
        width: 100,
        renderCell: (params) => {
            return (
                <div className="action">
                    <Link to="">
                        <img src="/Dashboard/view.svg" alt="" />
                    </Link>
                    <div className="delete" onClick={() => {
                        getUser(params.row.id)
                            .then(() => fetchUsers())
                            .catch(err => console.error("删除失败:", err))
                    }}>
                        <img src="/Dashboard/delete.svg" alt="" />
                    </div>
                </div>
            );
        },
    }
]

const Users = () => {
    const [open, setOpen] = useState(false)
    const [userRows, setUserRows] = useState([]);

    const fetchUsers = async () => {
            const res = await axios.get('/api/auth/allUsers');
            const usersWithId = res.data.data.map(user => ({
                ...user,
                id: user._id,
                verified: user.isVerified,
                phoneNumber: user.phoneNumber
            }));
            setUserRows(usersWithId);
    }

    const columns = getColumns(fetchUsers);

    useEffect(() => {
        fetchUsers();
    }, []);

    const toggleModal = () => {
        setOpen(!open);
    };

    return (
        <div className="users">
            <div className="info">
                <h1>Users</h1>
                <button className="add-user-btn" onClick={fetchUsers}><h4>Refresh</h4></button>
                <AddUserBtn onClick={toggleModal} />
            </div>
            <DataTable slug="users" columns={columns} rows={userRows} />

            {open && <AddUserForm setOpen={setOpen} />}
        </div>
    )
}

export default Users;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 12:57:03