如何实时更新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
相关产品推荐
相关产品推荐

