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

如何实时更新textarea内容并通过防抖优化实现2秒后调用API以提升性能

如何实时更新textarea内容并通过防抖优化实现2秒后调用API以提升性能

嘿,我来帮你解决这个问题!你想要实时更新textarea的内容,同时用防抖来避免每次按键都触发API调用,这个思路完全没问题,但现在防抖没起作用的原因是:每次组件重新渲染(比如调用setText更新状态时),都会重新创建一个新的_.debounce实例,导致每次按键触发的都是不同的防抖函数,自然每个都会延迟2秒后执行,达不到真正的防抖效果。

下面给你两种可行的解决方案,核心都是确保整个组件生命周期里只创建一次防抖函数实例:

方案一:使用useRef保存防抖函数引用

useRef的引用在组件整个生命周期内不会改变,刚好可以用来保存唯一的防抖函数实例:

import { useState, useRef, useEffect } from 'react';
import _ from 'lodash';

export default function App() {
  const [text, setText] = useState("");
  // 用useRef存储防抖函数实例
  const debouncedAPI = useRef<_.DebouncedFunc<(value: string) => void>>();

  useEffect(() => {
    // 初始化防抖函数,仅在组件挂载时执行一次
    debouncedAPI.current = _.debounce((value) => {
      console.log(value);
      // 在这里调用你的API
    }, 2000);

    // 组件卸载时取消未执行的防抖调用,避免无效请求或内存泄漏
    return () => {
      debouncedAPI.current?.cancel();
    };
  }, []);

  function onChangeText(e) {
    const value = e.target.value;
    console.log(`value inside onChangeText: ${value}`);
    setText(value);
    // 调用保存的同一个防抖函数实例
    debouncedAPI.current?.(value);
  }

  return (
    <div className="App">
      <textarea
        name="textarea"
        id=""
        value={text}
        onChange={onChangeText}
      ></textarea>
    </div>
  );
}

方案二:使用useCallback包裹防抖函数

useCallback可以缓存函数实例,依赖项设为空数组时,只会在组件挂载时创建一次:

import { useState, useCallback, useEffect } from 'react';
import _ from 'lodash';

export default function App() {
  const [text, setText] = useState("");

  // 用useCallback缓存防抖函数,确保仅创建一次
  const debouncedAPI = useCallback(
    _.debounce((value: string) => {
      console.log(value);
      // 在这里调用你的API
    }, 2000),
    []
  );

  // 组件卸载时清理防抖函数
  useEffect(() => {
    return () => {
      debouncedAPI.cancel();
    };
  }, [debouncedAPI]);

  function onChangeText(e) {
    const value = e.target.value;
    console.log(`value inside onChangeText: ${value}`);
    setText(value);
    debouncedAPI(value);
  }

  return (
    <div className="App">
      <textarea
        name="textarea"
        id=""
        value={text}
        onChange={onChangeText}
      ></textarea>
    </div>
  );
}

这两种方案都能实现:用户输入时实时更新textarea内容,只有当用户停止输入2秒后,才会触发一次API调用,完美解决性能问题~

备注:内容来源于stack exchange,提问作者DecPK

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 16:29:29