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

React多表单场景:无useRef实现输入停止后延迟更新State

解决方案:实现输入防抖避免Quill组件卡顿(不使用useRef)

原代码存在的问题

  1. 实时更新状态触发频繁渲染:handleDescription中每次输入都调用setEditors,直接触发组件重渲染,这是导致Quill卡顿的核心原因。
  2. 闭包导致状态无法更新:useEffect的依赖数组为空,内部setInterval捕获的call、currentIndex、editors都是组件初始化时的旧值,后续状态更新后无法读取最新数据,逻辑完全失效。
  3. 未清除重复定时器:每次输入都会创建新的setTimeout,旧定时器未被清除,会导致多次触发setCall(true),逻辑混乱。

修正后的实现代码

const [pendingUpdate, setPendingUpdate] = useState<{ index: number; value: any } | null>(null);
const [editors, setEditors] = useState({});

const handleDescription = (e: any, index: number) => {
    // 记录最新的输入内容和索引
    setPendingUpdate({ index, value: e });
};

// 利用useEffect监听pendingUpdate变化,实现防抖逻辑
useEffect(() => {
    if (!pendingUpdate) return;

    // 设置2秒后执行更新
    const timer = setTimeout(() => {
        const { index, value } = pendingUpdate;
        // 更新状态
        setEditors(prev => ({ ...prev, [index]: value }));
        // 调用目标函数
        Work.Description(props, index, value);
        // 清空待更新标记
        setPendingUpdate(null);
    }, 2000);

    // 组件重新渲染(或pendingUpdate变化)时,清除之前的定时器
    return () => clearTimeout(timer);
}, [pendingUpdate, props]);

return (
    <Container>
        <Items>
            {props.resume.employmentHistory.positions.map((position: any, index: number) => (
                <Editor
                    key={index}
                    label="Description"
                    value={position.description || ''}
                    onChange={(e) => handleDescription(e, index)}
                />
            ))}
        </Items>
    </Container>
);

关键逻辑说明

  • 用状态管理待更新内容:通过pendingUpdate状态存储最新的输入值和索引,避免实时更新editors触发渲染。
  • 防抖依赖useEffect实现:每次pendingUpdate变化时,清除之前的定时器并重新设置,确保只有用户停止输入2秒后才执行最终的状态更新和函数调用。
  • 避免闭包问题:useEffect依赖pendingUpdate,每次状态变化都会重新创建定时器,内部能获取到最新的待更新数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 22:09:15