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

React表格删除行后无法刷新,reload状态引发参数未定义求助

问题:React删除用户后表格无法刷新,添加reload状态导致删除请求ID未定义

问题背景

这是一个从API获取数据生成表格的React组件,表格行的删除按钮会触发确认模态框。为避免组件首次渲染时误触发api.delete请求,通过useRef设置effectRan初始值为false。点击模态框的Delete按钮后,后端已成功删除用户,但前端表格未自动刷新。尝试添加reload状态作为useEffect依赖来触发重新获取数据,虽然能实现表格刷新,但会导致api.delete请求中的ida参数变为未定义。


原组件代码

import React, { Fragment, useEffect, useState, useRef } from "react";
... other imports ... 

export default function AllUsers() {
  const api = useApi();
  const [userData, setUserData] = useState();
  const [showModal, setShowModal] = useState(false);
  const navigate = useNavigate();
  const [modalMessage, setModalMessage] = useState();
  const [removeUserId, setRemoveUserId] = useState();
  const [ida, setIda] = useState();
  let effectRan = useRef(false);
  const [reload, setReload] = useState(false);

  useEffect(() => {
    (async () => {
      const response = await api.get("/admin/users");
      if (response.ok) {
        setUserData(response.body);
      } else {
        setUserData(null);
      }
    })();
  }, [api]);

  useEffect(() => {
    if (effectRan.current) {
      (async () => {
        const response = await api.delete("/admin/users", {
          ida: ida,
        });
        if (response.ok && response.status === 204) {
          console.log(response);
        } else {
          console.log(response.body.errors);
        }
      })();
    }
    return () => (effectRan.current = true);
  }, [api, ida]);

  const handleEditClick = (e, rowIndex) => {
    navigate("/user/" + rowIndex.username, [navigate]);
  };

  const handleRemoveClick = (e, rowIndex) => {
    setShowModal(true);
    setModalMessage({
      title: `Remove ${rowIndex.username}`,
      message: `User's email to remove ${rowIndex.email}`,
    });
    setRemoveUserId(rowIndex.id);
  };

  const closeHandler = () => {
    setShowModal(false);
  };

  const deleteHandler = () => {
    setIda(removeUserId);
    setShowModal(false);
  };

  return (
    <Fragment>
      {showModal && (
        <BtModal
          show={showModal}
          title={modalMessage.title}
          message={modalMessage.message}
          handleClose={closeHandler}
          onConfirm={deleteHandler}
        />
      )}
      <Body>
        <h1>User Table</h1>

        {userData === undefined ? (
          <Spinner animation="border" />
        ) : (
          <>
            {userData === null ? (
              <p>Could not retrieve users.</p>
            ) : userData.length === 0 ? (
              <p>There are not users in system</p>
            ) : (
              <UserListTable
                newData={userData}
                handleEditClick={handleEditClick}
                handleRemoveClick={handleRemoveClick}
              />
            )}
          </>
        )}
      </Body>
    </Fragment>
  );
}

添加reload状态后的useEffect代码

useEffect(() => {
    (async () => {
      const response = await api.get("/admin/users");
      if (response.ok) {
        setUserData(response.body);
        effectRan.current = false;
      } else {
        setUserData(null);
      }
    })();
  }, [api, reload]);

  useEffect(() => {
    if (effectRan.current) {
      (async () => {
        const response = await api.delete("/admin/users", {
          ida: ida,
        });
        if (response.ok && response.status === 204) {
          console.log(response);
          setReload(!reload);
        } else {
          console.log(response.body.errors);
        }
      })();
    }
    return () => (effectRan.current = true);
  }, [api, ida, reload]);

解决方案

方案1:删除后直接更新本地数据(无需重复请求API)

无需依赖额外状态,删除成功后直接过滤本地数据,响应更快:

// 修改删除逻辑的useEffect
useEffect(() => {
  // 增加ida存在的判断,避免无效请求
  if (effectRan.current && ida) {
    (async () => {
      const response = await api.delete("/admin/users", {
        ida: ida,
      });
      if (response.ok && response.status === 204) {
        // 直接过滤掉已删除的用户,更新本地状态
        setUserData(prevData => prevData.filter(user => user.id !== ida));
      } else {
        console.log(response.body.errors);
      }
    })();
  }
  return () => (effectRan.current = true);
}, [api, ida]);

方案2:修复reload状态导致的ida未定义问题

问题根源是setReload(!reload)触发useEffect重复执行时,ida可能因状态异步更新出现异常,调整依赖和更新逻辑:

// 获取数据的useEffect保持不变
useEffect(() => {
  (async () => {
    const response = await api.get("/admin/users");
    if (response.ok) {
      setUserData(response.body);
    } else {
      setUserData(null);
    }
  })();
}, [api, reload]);

// 删除逻辑的useEffect去掉reload依赖,用函数式更新reload
useEffect(() => {
  if (effectRan.current && ida) {
    (async () => {
      const response = await api.delete("/admin/users", {
        ida: ida,
      });
      if (response.ok && response.status === 204) {
        // 函数式更新确保拿到最新的reload状态
        setReload(prev => !prev);
        // 重置ida,避免重复触发请求
        setIda(null);
      } else {
        console.log(response.body.errors);
      }
    })();
  }
  return () => (effectRan.current = true);
}, [api, ida]);

方案3:简化逻辑,直接在deleteHandler中处理

去掉冗余的ida状态和中转的useEffect,直接在删除确认函数中完成请求和刷新:

// 删除原有的ida状态和第二个useEffect
const deleteHandler = async () => {
  setShowModal(false);
  if (!removeUserId) return;
  
  const response = await api.delete("/admin/users", {
    ida: removeUserId,
  });
  if (response.ok && response.status === 204) {
    // 本地更新数据(推荐)
    setUserData(prev => prev.filter(user => user.id !== removeUserId));
    // 或者触发重新请求:
    // setReload(prev => !prev);
  } else {
    console.log(response.body.errors);
  }
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 14:35:40