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

React useEffect仅首次删除触发,AgGridReact无法重复更新

问题分析与解决方案

问题根源

你的代码中,deleteHandler被用作AgGrid的cellRenderer回调,但AgGrid会缓存cellRenderer组件,导致首次渲染时的deleteHandler被一直复用。这个旧的deleteHandler捕获了初始的productDeleted=false状态,后续每次删除时调用setProductDeleted(!productDeleted),本质是把状态从true再次设置为true(因为闭包中的productDeleted始终是初始的false)——状态没有发生实际变化,所以useEffect不会触发,网格也就无法更新。

同时你看到的console.log(productDeleted)始终为false,是因为React状态更新是异步的,set操作后的console.log读取的仍是更新前的旧值。

解决方案

方案1:使用函数式更新切换状态

通过函数式更新获取最新状态,避免闭包捕获旧值的问题,确保每次删除都能触发状态变化:

const deleteHandler = (productId) => {
  if (
    window.confirm(
      "Voulez-vous vraiment supprimer ce produit ?\nCette action est irreversible."
    )
  ) {
    deleteProduct(productId)
      .then(data => {
        if (data === "Product deleted") {
          // 使用函数式更新,基于最新状态取反
          setProductDeleted(prevState => !prevState);
          window.alert("Produit supprimé !");
        } else {
          console.error(data);
        }
      })
      .catch(err => console.error(err))
  }
};

方案2:删除成功后直接更新数据(推荐)

去掉productDeleted状态,删除成功后直接调用接口刷新数据,逻辑更直观,也能彻底规避闭包问题:

const deleteHandler = (productId) => {
  if (
    window.confirm(
      "Voulez-vous vraiment supprimer ce produit ?\nCette action est irreversible."
    )
  ) {
    deleteProduct(productId)
      .then(data => {
        if (data === "Product deleted") {
          const abctrl = new AbortController();
          // 删除成功后直接重新获取数据并更新网格
          fetchProducts(abctrl)
            .then(rawData => formatData(rawData))
            .then(formattedData => setRowData(formattedData))
            .catch(er => {
              const errorMessage = er.response.data.message
                ? er.response.data.message
                : er.response.data;
              redirectionFromAdminPages(errorMessage, reduxDispatch);
            });
          window.alert("Produit supprimé !");
        } else {
          console.error(data);
        }
      })
      .catch(err => console.error(err))
  }
};

同时修改useEffect的依赖,去掉productDeleted:

useEffect(() => {
  console.log("useEffect...")
  const abctrl = new AbortController();
  fetchProducts(abctrl)
    .then((data) => formatData(data))
    .then((res) => setRowData(res))
    .catch((er) => {
      const errorMessage = er.response.data.message
        ? er.response.data.message
        : er.response.data;
      redirectionFromAdminPages(errorMessage, reduxDispatch);
    });

  return () => abctrl.abort();
}, [fetchProducts, reduxDispatch]);

方案3:确保cellRenderer获取最新的deleteHandler

通过AgGrid的cellRendererParams传递最新的回调函数,配合useCallback稳定函数引用:

  1. 用useCallback包裹deleteHandler:
import { useCallback } from "react";

// ...

const deleteHandler = useCallback((productId) => {
  if (
    window.confirm(
      "Voulez-vous vraiment supprimer ce produit ?\nCette action est irreversible."
    )
  ) {
    deleteProduct(productId)
      .then(data => {
        if (data === "Product deleted") {
          setProductDeleted(prev => !prev);
          window.alert("Produit supprimé !");
        } else {
          console.error(data);
        }
      })
      .catch(err => console.error(err))
  }
}, [deleteProduct]);
  1. 修改列定义,传递回调参数:
// 修改editOrDelete列的配置
{
  field: "editOrDelete",
  headerName: "Modifier / Supprimer",
  width: 150,
  filter: false,
  cellRenderer: editOrDeleteBtn,
  cellRendererParams: {
    deleteHandler: deleteHandler
  }
}
  1. 更新cellRenderer使用传递的回调:
const editOrDeleteBtn = (params) => {
  return (
    <>
      <LinkContainer to={`/admin/modifier-produit/${params.value}`}>
        <Button className="btn-sm">
          <i className="bi bi-pencil-square"></i>
        </Button>
      </LinkContainer>
      {" / "}
      <Button
        className="btn-sm"
        variant="danger"
        onClick={() => params.deleteHandler(params.value)}
      >
        <i className="bi bi-x-circle"></i>
      </Button>
    </>
  );
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 14:55:55