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

React输入框onBlur触发patch后短暂显示旧值的解决方案咨询

解决输入框在patch成功后短暂显示旧值的问题

问题原因

在handleBlur方法中,调用mutate提交更新后立刻执行setValue(parseFloat(cell.getValue())),此时服务器尚未完成数据更新,cell.getValue()返回的仍是旧值,导致输入框先显示旧值;待服务器更新完成后,cell.getValue()变为新值,监听该值的useEffect触发,将输入框值切换为新值,因此出现短暂显示旧值的闪烁现象。

解决方案

通过调整本地状态更新时机,避免强制覆盖为旧值,同时确保输入框立刻显示提交后的正确值:

  1. 移除handleBlur末尾强制设置旧值的setValue(parseFloat(cell.getValue()))语句;
  2. 在调用mutate提交前,先将本地状态更新为处理后的目标值,让输入框立刻显示正确结果;
  3. 统一状态类型为字符串,避免数字与字符串切换引发的类型不一致问题;
  4. 增加错误处理,确保非法输入或提交失败时状态能正确回滚。

修改后的完整代码

import { useEffect, useRef, useState } from "react";

export const TableNumberInput = ({
  cell,
  mutate,
  ...restProps
}: {
  cell: unknown;
  mutate: unknown;
}) => {
  // 初始化状态为字符串,与输入框值类型保持一致
  const [value, setValue] = useState(cell.getValue().toString());

  const inputRef = useRef(null);

  useEffect(() => {
    // 当cell数据更新时,同步到本地状态
    setValue(cell.getValue().toString());
  }, [cell.getValue()]);

  const handleBlur = (event) => {
    try {
      const num = eval(event.target.value);
      const rounded_num = Math.round(num * 100) / 100;
      const roundedStr = rounded_num.toString();

      // 先更新本地状态,输入框立刻显示处理后的值
      setValue(roundedStr);

      if (parseFloat(value) !== parseFloat(cell.getValue())) {
        mutate(
          {
            id: cell.row.original.id.toString(),
            data: { [cell.column.id]: rounded_num },
          },
          {
            onError: () => {
              // 提交失败时恢复为cell原始值
              setValue(cell.getValue().toString());
              inputRef.current.select();
              inputRef.current.focus();
            },
          }
        );
      }
    } catch (err) {
      // 处理eval执行错误,恢复为原始值
      setValue(cell.getValue().toString());
      inputRef.current.select();
      inputRef.current.focus();
    }
  };

  return (
    <input
      ref={inputRef}
      value={value}
      onChange={(e) => setValue(e.target.value)}
      precision={2}
      onBlur={handleBlur}
      {...restProps}
    />
  );
};

关键修改说明

  • 移除旧值强制设置:避免提交后立刻将输入框切回旧值,消除闪烁根源;
  • 提前更新本地状态:提交前先把输入框值设为处理后的结果,用户无需等待服务器响应即可看到正确显示;
  • 类型统一:将状态值统一为字符串,避免数字与字符串类型切换导致的渲染异常;
  • 错误处理增强:覆盖eval执行错误和提交失败场景,确保状态能正确回滚,提升用户体验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 11:40:54