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

React中点击表格行时UseEffect频繁触发,求优化方案

解决点击表格行触发不必要更新的优化方案

核心问题

点击表格行初始化地址状态时,useEffect 会因状态变更触发 updateSubmittedApplication,但这只是初始化操作而非用户主动修改,需要区分这两种场景。

方案一:保存初始地址值,对比变化后再更新

新增状态存储初始地址信息,在 useEffect 中对比当前值与初始值,仅当存在实际修改时触发更新。

// 新增初始地址状态
const [initialAddress, setInitialAddress] = useState({});

const rowEvents = {
  onClick: (e, row) => {
    toggleTrueFalse();
    setModalInfo(row);
    // 同时保存初始地址和当前地址
    const addressData = {
      AddressLine1: row.AddressLine1,
      AddressLine2: row.AddressLine2,
      City: row.City,
      Province: row.Province,
      PostalCode: row.Postalcode
    };
    setInitialAddress(addressData);
    SetAddressLine1(row.AddressLine1);
    SetAddressLine2(row.AddressLine2);
    SetCity(row.City);
    SetProvince(row.Province);
    SetPostalcode(row.Postalcode);
  },
};

// 修改useEffect逻辑
useEffect(() => {
  // 对比当前地址和初始地址是否存在差异
  const hasChanged = Object.entries({
    AddressLine1: addressLine1,
    AddressLine2: addressLine2,
    City: city,
    Province: province,
    PostalCode: postalCode
  }).some(([key, value]) => value !== initialAddress[key]);

  if (hasChanged) {
    updateSubmittedApplication();
  }
}, [addressLine1, addressLine2, city, province, postalCode, initialAddress]);

方案二:移除useEffect,直接利用Editable组件的onSubmit事件

既然Editable组件本身提供了onSubmit回调,可直接将更新逻辑放在此处,完全避免依赖状态变化触发的副作用。

// 移除原有的useEffect

// 修改Editable组件的验证和提交逻辑
<Editable 
  editText="Edit"
  initialValue={addressLine1.toString()} 
  isValueClickable
  mode="inline"
  validate={(value) => {if(!value) return '地址不能为空';}} // 修正原验证逻辑的错误
  onValidated={(newValue) => {SetAddressLine1(newValue);}}
  onSubmit={() => {
    // 仅在用户主动提交编辑时触发更新
    updateSubmittedApplication();
  }}
  type="textfield"
/>

方案三:合并地址状态为单个对象,简化对比逻辑

将分散的地址状态合并为一个对象,既减少状态数量,也更容易对比初始值与当前值:

// 合并地址状态为单个对象
const [address, setAddress] = useState({
  AddressLine1: '',
  AddressLine2: '',
  City: '',
  Province: '',
  PostalCode: ''
});
const [initialAddress, setInitialAddress] = useState({});

const rowEvents = {
  onClick: (e, row) => {
    toggleTrueFalse();
    setModalInfo(row);
    const addressData = {
      AddressLine1: row.AddressLine1,
      AddressLine2: row.AddressLine2,
      City: row.City,
      Province: row.Province,
      PostalCode: row.Postalcode
    };
    setInitialAddress(addressData);
    setAddress(addressData);
  },
};

// 修改Editable组件的属性
<Editable 
  editText="Edit"
  initialValue={address.AddressLine1.toString()} 
  isValueClickable
  mode="inline"
  validate={(value) => {if(!value) return '地址不能为空';}}
  onValidated={(newValue) => {
    setAddress(prev => ({...prev, AddressLine1: newValue}));
  }}
  onSubmit={updateSubmittedApplication}
  type="textfield"
/>

// 修改更新函数和useEffect
const updateSubmittedApplication = () => {
  const id = modalInfo.Id;
  if (Object.values(address).some(val => val)) {
    axiosPrivate.put(`/updateapp/${id}`, address)
    .then((res) => {
      getSubmittedData();
      // 修正原状态更新逻辑的错误:用map替换新增操作,避免重复数据
      const latestSubmitInfo = submitted.map(item => 
        item.Id === id ? {...item, ...address} : item
      );
      setSubmitted(latestSubmitInfo);
      console.log(res.data);
    }); 
  } 
};

useEffect(() => {
  // 对比对象是否存在变化
  const hasChanged = Object.entries(address).some(([key, val]) => val !== initialAddress[key]);
  if (hasChanged) {
    updateSubmittedApplication();
  }
}, [address, initialAddress]);

额外优化提示

  • 原updateSubmittedApplication中更新submitted状态的逻辑有误,使用map替换[...submitted, updatedSubmit]可避免重复添加数据。
  • 原validate函数逻辑颠倒,应在值为空时返回错误提示,否则不返回内容。

内容的提问来源于stack exchange,提问作者It hurts when IP

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 02:10:32