添加debounce防抖后React Final Form的FormSpy中API返回数据undefined求解
问题原因
lodash.debounce包装后的函数默认不会返回内部异步逻辑的Promise实例:调用debouncedSave(value)时,防抖逻辑会立刻返回undefined,不会等待内部getSuggestedSections请求执行完成,因此外层的await没有实际作用,拿到的data自然是undefined。虽然请求本身正常触发、网络面板可看到返回结果,但返回值没有传递到外层调用位置。- 额外隐患:当前代码未对防抖函数做卸载清理,组件卸载时如果还有待执行的防抖任务,可能触发内存泄漏或已卸载组件的状态更新警告。
解决方法
推荐将依赖返回值的逻辑全部放到防抖包裹的函数内部,同时补充防抖清理逻辑,修改后代码如下:
import { FormSpy } from 'react-final-form'; import { OnChange } from 'react-final-form-listeners'; import _ from 'lodash'; import { useCallback, useEffect } from 'react'; function Component({ handleFunction, input, }: { handleFunction: any; input: any; }) { const debouncedSave = useCallback( _.debounce(async (newValue) => { const data = await getSuggestedSections(newValue); // 所有需要用到返回值的逻辑都放在此处执行 console.log(newValue); console.log(data); // 如需联动更新其他表单字段,可在此处调用form.change等API }, 1000), [], ); // 组件卸载时取消待执行的防抖任务 useEffect(() => { return () => { debouncedSave.cancel(); }; }, [debouncedSave]); return ( <FormSpy subscription={{ dirty: true, values: true }}> {() => ( <OnChange name="item-name"> {(value) => { // 直接调用防抖函数即可,无需await和接收返回值 debouncedSave(value); }} </OnChange> )} </FormSpy> ); }
额外注意事项
- 如果
getSuggestedSections依赖组件内部的props或state,需要把对应的变量添加到useCallback的依赖数组中,避免闭包陷阱。 - 如果确实需要在外层获取防抖函数的返回值,可自定义支持Promise返回的防抖函数,不要依赖lodash默认的防抖实现。
内容的提问来源于stack exchange,提问作者deptdev
相关产品推荐
相关产品推荐

